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

TOMOYO Linux Cross Reference
Linux/fs/nilfs2/the_nilfs.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/nilfs2/the_nilfs.c (Version linux-6.12-rc7) and /fs/nilfs2/the_nilfs.c (Version policy-sample)


  1 // SPDX-License-Identifier: GPL-2.0+                1 
  2 /*                                                
  3  * the_nilfs shared structure.                    
  4  *                                                
  5  * Copyright (C) 2005-2008 Nippon Telegraph an    
  6  *                                                
  7  * Written by Ryusuke Konishi.                    
  8  *                                                
  9  */                                               
 10                                                   
 11 #include <linux/buffer_head.h>                    
 12 #include <linux/slab.h>                           
 13 #include <linux/blkdev.h>                         
 14 #include <linux/backing-dev.h>                    
 15 #include <linux/log2.h>                           
 16 #include <linux/crc32.h>                          
 17 #include "nilfs.h"                                
 18 #include "segment.h"                              
 19 #include "alloc.h"                                
 20 #include "cpfile.h"                               
 21 #include "sufile.h"                               
 22 #include "dat.h"                                  
 23 #include "segbuf.h"                               
 24                                                   
 25                                                   
 26 static int nilfs_valid_sb(struct nilfs_super_b    
 27                                                   
 28 void nilfs_set_last_segment(struct the_nilfs *    
 29                             sector_t start_blo    
 30 {                                                 
 31         spin_lock(&nilfs->ns_last_segment_lock    
 32         nilfs->ns_last_pseg = start_blocknr;      
 33         nilfs->ns_last_seq = seq;                 
 34         nilfs->ns_last_cno = cno;                 
 35                                                   
 36         if (!nilfs_sb_dirty(nilfs)) {             
 37                 if (nilfs->ns_prev_seq == nilf    
 38                         goto stay_cursor;         
 39                                                   
 40                 set_nilfs_sb_dirty(nilfs);        
 41         }                                         
 42         nilfs->ns_prev_seq = nilfs->ns_last_se    
 43                                                   
 44  stay_cursor:                                     
 45         spin_unlock(&nilfs->ns_last_segment_lo    
 46 }                                                 
 47                                                   
 48 /**                                               
 49  * alloc_nilfs - allocate a nilfs object          
 50  * @sb: super block instance                      
 51  *                                                
 52  * Return Value: On success, pointer to the_ni    
 53  * On error, NULL is returned.                    
 54  */                                               
 55 struct the_nilfs *alloc_nilfs(struct super_blo    
 56 {                                                 
 57         struct the_nilfs *nilfs;                  
 58                                                   
 59         nilfs = kzalloc(sizeof(*nilfs), GFP_KE    
 60         if (!nilfs)                               
 61                 return NULL;                      
 62                                                   
 63         nilfs->ns_sb = sb;                        
 64         nilfs->ns_bdev = sb->s_bdev;              
 65         atomic_set(&nilfs->ns_ndirtyblks, 0);     
 66         init_rwsem(&nilfs->ns_sem);               
 67         mutex_init(&nilfs->ns_snapshot_mount_m    
 68         INIT_LIST_HEAD(&nilfs->ns_dirty_files)    
 69         INIT_LIST_HEAD(&nilfs->ns_gc_inodes);     
 70         spin_lock_init(&nilfs->ns_inode_lock);    
 71         spin_lock_init(&nilfs->ns_last_segment    
 72         nilfs->ns_cptree = RB_ROOT;               
 73         spin_lock_init(&nilfs->ns_cptree_lock)    
 74         init_rwsem(&nilfs->ns_segctor_sem);       
 75         nilfs->ns_sb_update_freq = NILFS_SB_FR    
 76                                                   
 77         return nilfs;                             
 78 }                                                 
 79                                                   
 80 /**                                               
 81  * destroy_nilfs - destroy nilfs object           
 82  * @nilfs: nilfs object to be released            
 83  */                                               
 84 void destroy_nilfs(struct the_nilfs *nilfs)       
 85 {                                                 
 86         might_sleep();                            
 87         if (nilfs_init(nilfs)) {                  
 88                 brelse(nilfs->ns_sbh[0]);         
 89                 brelse(nilfs->ns_sbh[1]);         
 90         }                                         
 91         kfree(nilfs);                             
 92 }                                                 
 93                                                   
 94 static int nilfs_load_super_root(struct the_ni    
 95                                  struct super_    
 96 {                                                 
 97         struct buffer_head *bh_sr;                
 98         struct nilfs_super_root *raw_sr;          
 99         struct nilfs_super_block **sbp = nilfs    
100         struct nilfs_inode *rawi;                 
101         unsigned int dat_entry_size, segment_u    
102         unsigned int inode_size;                  
103         int err;                                  
104                                                   
105         err = nilfs_read_super_root_block(nilf    
106         if (unlikely(err))                        
107                 return err;                       
108                                                   
109         down_read(&nilfs->ns_sem);                
110         dat_entry_size = le16_to_cpu(sbp[0]->s    
111         checkpoint_size = le16_to_cpu(sbp[0]->    
112         segment_usage_size = le16_to_cpu(sbp[0    
113         up_read(&nilfs->ns_sem);                  
114                                                   
115         inode_size = nilfs->ns_inode_size;        
116                                                   
117         rawi = (void *)bh_sr->b_data + NILFS_S    
118         err = nilfs_dat_read(sb, dat_entry_siz    
119         if (err)                                  
120                 goto failed;                      
121                                                   
122         rawi = (void *)bh_sr->b_data + NILFS_S    
123         err = nilfs_cpfile_read(sb, checkpoint    
124         if (err)                                  
125                 goto failed_dat;                  
126                                                   
127         rawi = (void *)bh_sr->b_data + NILFS_S    
128         err = nilfs_sufile_read(sb, segment_us    
129                                 &nilfs->ns_suf    
130         if (err)                                  
131                 goto failed_cpfile;               
132                                                   
133         raw_sr = (struct nilfs_super_root *)bh    
134         nilfs->ns_nongc_ctime = le64_to_cpu(ra    
135                                                   
136  failed:                                          
137         brelse(bh_sr);                            
138         return err;                               
139                                                   
140  failed_cpfile:                                   
141         iput(nilfs->ns_cpfile);                   
142                                                   
143  failed_dat:                                      
144         iput(nilfs->ns_dat);                      
145         goto failed;                              
146 }                                                 
147                                                   
148 static void nilfs_init_recovery_info(struct ni    
149 {                                                 
150         memset(ri, 0, sizeof(*ri));               
151         INIT_LIST_HEAD(&ri->ri_used_segments);    
152 }                                                 
153                                                   
154 static void nilfs_clear_recovery_info(struct n    
155 {                                                 
156         nilfs_dispose_segment_list(&ri->ri_use    
157 }                                                 
158                                                   
159 /**                                               
160  * nilfs_store_log_cursor - load log cursor fr    
161  * @nilfs: nilfs object                           
162  * @sbp: buffer storing super block to be read    
163  *                                                
164  * nilfs_store_log_cursor() reads the last pos    
165  * containing a super root from a given super     
166  * relevant information on the nilfs object pr    
167  * scanning and recovery.                         
168  */                                               
169 static int nilfs_store_log_cursor(struct the_n    
170                                   struct nilfs    
171 {                                                 
172         int ret = 0;                              
173                                                   
174         nilfs->ns_last_pseg = le64_to_cpu(sbp-    
175         nilfs->ns_last_cno = le64_to_cpu(sbp->    
176         nilfs->ns_last_seq = le64_to_cpu(sbp->    
177                                                   
178         nilfs->ns_prev_seq = nilfs->ns_last_se    
179         nilfs->ns_seg_seq = nilfs->ns_last_seq    
180         nilfs->ns_segnum =                        
181                 nilfs_get_segnum_of_block(nilf    
182         nilfs->ns_cno = nilfs->ns_last_cno + 1    
183         if (nilfs->ns_segnum >= nilfs->ns_nseg    
184                 nilfs_err(nilfs->ns_sb,           
185                           "pointed segment num    
186                           (unsigned long long)    
187                           nilfs->ns_nsegments)    
188                 ret = -EINVAL;                    
189         }                                         
190         return ret;                               
191 }                                                 
192                                                   
193 /**                                               
194  * nilfs_get_blocksize - get block size from r    
195  * @sb: super block instance                      
196  * @sbp: superblock raw data buffer               
197  * @blocksize: place to store block size          
198  *                                                
199  * nilfs_get_blocksize() calculates the block     
200  * exponent information written in @sbp and st    
201  * or aborts with an error message if it's too    
202  *                                                
203  * Return Value: On success, 0 is returned. If    
204  * large, -EINVAL is returned.                    
205  */                                               
206 static int nilfs_get_blocksize(struct super_bl    
207                                struct nilfs_su    
208 {                                                 
209         unsigned int shift_bits = le32_to_cpu(    
210                                                   
211         if (unlikely(shift_bits >                 
212                      ilog2(NILFS_MAX_BLOCK_SIZ    
213                 nilfs_err(sb, "too large files    
214                           shift_bits);            
215                 return -EINVAL;                   
216         }                                         
217         *blocksize = BLOCK_SIZE << shift_bits;    
218         return 0;                                 
219 }                                                 
220                                                   
221 /**                                               
222  * load_nilfs - load and recover the nilfs        
223  * @nilfs: the_nilfs structure to be released     
224  * @sb: super block instance used to recover p    
225  *                                                
226  * load_nilfs() searches and load the latest s    
227  * attaches the last segment, and does recover    
228  * The caller must call this exclusively for s    
229  */                                               
230 int load_nilfs(struct the_nilfs *nilfs, struct    
231 {                                                 
232         struct nilfs_recovery_info ri;            
233         unsigned int s_flags = sb->s_flags;       
234         int really_read_only = bdev_read_only(    
235         int valid_fs = nilfs_valid_fs(nilfs);     
236         int err;                                  
237                                                   
238         if (!valid_fs) {                          
239                 nilfs_warn(sb, "mounting unche    
240                 if (s_flags & SB_RDONLY) {        
241                         nilfs_info(sb,            
242                                    "recovery r    
243                         nilfs_info(sb,            
244                                    "write acce    
245                 }                                 
246         }                                         
247                                                   
248         nilfs_init_recovery_info(&ri);            
249                                                   
250         err = nilfs_search_super_root(nilfs, &    
251         if (unlikely(err)) {                      
252                 struct nilfs_super_block **sbp    
253                 int blocksize;                    
254                                                   
255                 if (err != -EINVAL)               
256                         goto scan_error;          
257                                                   
258                 if (!nilfs_valid_sb(sbp[1])) {    
259                         nilfs_warn(sb,            
260                                    "unable to     
261                         goto scan_error;          
262                 }                                 
263                 nilfs_info(sb, "trying rollbac    
264                                                   
265                 /*                                
266                  * restore super block with it    
267                  * relevant states of the nilf    
268                  */                               
269                 memcpy(sbp[0], sbp[1], nilfs->    
270                 nilfs->ns_crc_seed = le32_to_c    
271                 nilfs->ns_sbwtime = le64_to_cp    
272                                                   
273                 /* verify consistency between     
274                 err = nilfs_get_blocksize(sb,     
275                 if (err)                          
276                         goto scan_error;          
277                                                   
278                 if (blocksize != nilfs->ns_blo    
279                         nilfs_warn(sb,            
280                                    "blocksize     
281                                    blocksize,     
282                         err = -EINVAL;            
283                         goto scan_error;          
284                 }                                 
285                                                   
286                 err = nilfs_store_log_cursor(n    
287                 if (err)                          
288                         goto scan_error;          
289                                                   
290                 /* drop clean flag to allow ro    
291                 nilfs->ns_mount_state &= ~NILF    
292                 valid_fs = 0;                     
293                                                   
294                 err = nilfs_search_super_root(    
295                 if (err)                          
296                         goto scan_error;          
297         }                                         
298                                                   
299         err = nilfs_load_super_root(nilfs, sb,    
300         if (unlikely(err)) {                      
301                 nilfs_err(sb, "error %d while     
302                 goto failed;                      
303         }                                         
304                                                   
305         err = nilfs_sysfs_create_device_group(    
306         if (unlikely(err))                        
307                 goto sysfs_error;                 
308                                                   
309         if (valid_fs)                             
310                 goto skip_recovery;               
311                                                   
312         if (s_flags & SB_RDONLY) {                
313                 __u64 features;                   
314                                                   
315                 if (nilfs_test_opt(nilfs, NORE    
316                         nilfs_info(sb,            
317                                    "norecovery    
318                         goto skip_recovery;       
319                 }                                 
320                 features = le64_to_cpu(nilfs->    
321                         ~NILFS_FEATURE_COMPAT_    
322                 if (features) {                   
323                         nilfs_err(sb,             
324                                   "couldn't pr    
325                                   (unsigned lo    
326                         err = -EROFS;             
327                         goto failed_unload;       
328                 }                                 
329                 if (really_read_only) {           
330                         nilfs_err(sb,             
331                                   "write acces    
332                         err = -EROFS;             
333                         goto failed_unload;       
334                 }                                 
335                 sb->s_flags &= ~SB_RDONLY;        
336         } else if (nilfs_test_opt(nilfs, NOREC    
337                 nilfs_err(sb,                     
338                           "recovery cancelled     
339                 err = -EINVAL;                    
340                 goto failed_unload;               
341         }                                         
342                                                   
343         err = nilfs_salvage_orphan_logs(nilfs,    
344         if (err)                                  
345                 goto failed_unload;               
346                                                   
347         down_write(&nilfs->ns_sem);               
348         nilfs->ns_mount_state |= NILFS_VALID_F    
349         err = nilfs_cleanup_super(sb);            
350         up_write(&nilfs->ns_sem);                 
351                                                   
352         if (err) {                                
353                 nilfs_err(sb,                     
354                           "error %d updating s    
355                           err);                   
356                 goto failed_unload;               
357         }                                         
358         nilfs_info(sb, "recovery complete");      
359                                                   
360  skip_recovery:                                   
361         nilfs_clear_recovery_info(&ri);           
362         sb->s_flags = s_flags;                    
363         return 0;                                 
364                                                   
365  scan_error:                                      
366         nilfs_err(sb, "error %d while searchin    
367         goto failed;                              
368                                                   
369  failed_unload:                                   
370         nilfs_sysfs_delete_device_group(nilfs)    
371                                                   
372  sysfs_error:                                     
373         iput(nilfs->ns_cpfile);                   
374         iput(nilfs->ns_sufile);                   
375         iput(nilfs->ns_dat);                      
376                                                   
377  failed:                                          
378         nilfs_clear_recovery_info(&ri);           
379         sb->s_flags = s_flags;                    
380         return err;                               
381 }                                                 
382                                                   
383 static unsigned long long nilfs_max_size(unsig    
384 {                                                 
385         unsigned int max_bits;                    
386         unsigned long long res = MAX_LFS_FILES    
387                                                   
388         max_bits = blkbits + NILFS_BMAP_KEY_BI    
389         if (max_bits < 64)                        
390                 res = min_t(unsigned long long    
391         return res;                               
392 }                                                 
393                                                   
394 /**                                               
395  * nilfs_nrsvsegs - calculate the number of re    
396  * @nilfs: nilfs object                           
397  * @nsegs: total number of segments               
398  */                                               
399 unsigned long nilfs_nrsvsegs(struct the_nilfs     
400 {                                                 
401         return max_t(unsigned long, NILFS_MIN_    
402                      DIV_ROUND_UP(nsegs * nilf    
403                                   100));          
404 }                                                 
405                                                   
406 /**                                               
407  * nilfs_max_segment_count - calculate the max    
408  * @nilfs: nilfs object                           
409  */                                               
410 static u64 nilfs_max_segment_count(struct the_    
411 {                                                 
412         u64 max_count = U64_MAX;                  
413                                                   
414         max_count = div64_ul(max_count, nilfs-    
415         return min_t(u64, max_count, ULONG_MAX    
416 }                                                 
417                                                   
418 void nilfs_set_nsegments(struct the_nilfs *nil    
419 {                                                 
420         nilfs->ns_nsegments = nsegs;              
421         nilfs->ns_nrsvsegs = nilfs_nrsvsegs(ni    
422 }                                                 
423                                                   
424 static int nilfs_store_disk_layout(struct the_    
425                                    struct nilf    
426 {                                                 
427         u64 nsegments, nblocks;                   
428                                                   
429         if (le32_to_cpu(sbp->s_rev_level) < NI    
430                 nilfs_err(nilfs->ns_sb,           
431                           "unsupported revisio    
432                           le32_to_cpu(sbp->s_r    
433                           le16_to_cpu(sbp->s_m    
434                           NILFS_CURRENT_REV, N    
435                 return -EINVAL;                   
436         }                                         
437         nilfs->ns_sbsize = le16_to_cpu(sbp->s_    
438         if (nilfs->ns_sbsize > BLOCK_SIZE)        
439                 return -EINVAL;                   
440                                                   
441         nilfs->ns_inode_size = le16_to_cpu(sbp    
442         if (nilfs->ns_inode_size > nilfs->ns_b    
443                 nilfs_err(nilfs->ns_sb, "too l    
444                           nilfs->ns_inode_size    
445                 return -EINVAL;                   
446         } else if (nilfs->ns_inode_size < NILF    
447                 nilfs_err(nilfs->ns_sb, "too s    
448                           nilfs->ns_inode_size    
449                 return -EINVAL;                   
450         }                                         
451                                                   
452         nilfs->ns_first_ino = le32_to_cpu(sbp-    
453         if (nilfs->ns_first_ino < NILFS_USER_I    
454                 nilfs_err(nilfs->ns_sb,           
455                           "too small lower lim    
456                           nilfs->ns_first_ino)    
457                 return -EINVAL;                   
458         }                                         
459                                                   
460         nilfs->ns_blocks_per_segment = le32_to    
461         if (nilfs->ns_blocks_per_segment < NIL    
462                 nilfs_err(nilfs->ns_sb, "too s    
463                           nilfs->ns_blocks_per    
464                 return -EINVAL;                   
465         }                                         
466                                                   
467         nilfs->ns_first_data_block = le64_to_c    
468         nilfs->ns_r_segments_percentage =         
469                 le32_to_cpu(sbp->s_r_segments_    
470         if (nilfs->ns_r_segments_percentage <     
471             nilfs->ns_r_segments_percentage >     
472                 nilfs_err(nilfs->ns_sb,           
473                           "invalid reserved se    
474                           nilfs->ns_r_segments    
475                 return -EINVAL;                   
476         }                                         
477                                                   
478         nsegments = le64_to_cpu(sbp->s_nsegmen    
479         if (nsegments > nilfs_max_segment_coun    
480                 nilfs_err(nilfs->ns_sb,           
481                           "segment count %llu     
482                           (unsigned long long)    
483                           (unsigned long long)    
484                 return -EINVAL;                   
485         }                                         
486                                                   
487         nblocks = sb_bdev_nr_blocks(nilfs->ns_    
488         if (nblocks) {                            
489                 u64 min_block_count = nsegment    
490                 /*                                
491                  * To avoid failing to mount e    
492                  * second superblock, exclude     
493                  * "min_block_count" calculati    
494                  */                               
495                                                   
496                 if (nblocks < min_block_count)    
497                         nilfs_err(nilfs->ns_sb    
498                                   "total numbe    
499                                   (unsigned lo    
500                                   (unsigned lo    
501                         return -EINVAL;           
502                 }                                 
503         }                                         
504                                                   
505         nilfs_set_nsegments(nilfs, nsegments);    
506         nilfs->ns_crc_seed = le32_to_cpu(sbp->    
507         return 0;                                 
508 }                                                 
509                                                   
510 static int nilfs_valid_sb(struct nilfs_super_b    
511 {                                                 
512         static unsigned char sum[4];              
513         const int sumoff = offsetof(struct nil    
514         size_t bytes;                             
515         u32 crc;                                  
516                                                   
517         if (!sbp || le16_to_cpu(sbp->s_magic)     
518                 return 0;                         
519         bytes = le16_to_cpu(sbp->s_bytes);        
520         if (bytes < sumoff + 4 || bytes > BLOC    
521                 return 0;                         
522         crc = crc32_le(le32_to_cpu(sbp->s_crc_    
523                        sumoff);                   
524         crc = crc32_le(crc, sum, 4);              
525         crc = crc32_le(crc, (unsigned char *)s    
526                        bytes - sumoff - 4);       
527         return crc == le32_to_cpu(sbp->s_sum);    
528 }                                                 
529                                                   
530 /**                                               
531  * nilfs_sb2_bad_offset - check the location o    
532  * @sbp: superblock raw data buffer               
533  * @offset: byte offset of second superblock c    
534  *                                                
535  * nilfs_sb2_bad_offset() checks if the positi    
536  * superblock is valid or not based on the fil    
537  * stored in @sbp.  If @offset points to a loc    
538  * area, or if the parameters themselves are n    
539  * determined to be invalid.                      
540  *                                                
541  * Return Value: true if invalid, false if val    
542  */                                               
543 static bool nilfs_sb2_bad_offset(struct nilfs_    
544 {                                                 
545         unsigned int shift_bits = le32_to_cpu(    
546         u32 blocks_per_segment = le32_to_cpu(s    
547         u64 nsegments = le64_to_cpu(sbp->s_nse    
548         u64 index;                                
549                                                   
550         if (blocks_per_segment < NILFS_SEG_MIN    
551             shift_bits > ilog2(NILFS_MAX_BLOCK    
552                 return true;                      
553                                                   
554         index = offset >> (shift_bits + BLOCK_    
555         do_div(index, blocks_per_segment);        
556         return index < nsegments;                 
557 }                                                 
558                                                   
559 static void nilfs_release_super_block(struct t    
560 {                                                 
561         int i;                                    
562                                                   
563         for (i = 0; i < 2; i++) {                 
564                 if (nilfs->ns_sbp[i]) {           
565                         brelse(nilfs->ns_sbh[i    
566                         nilfs->ns_sbh[i] = NUL    
567                         nilfs->ns_sbp[i] = NUL    
568                 }                                 
569         }                                         
570 }                                                 
571                                                   
572 void nilfs_fall_back_super_block(struct the_ni    
573 {                                                 
574         brelse(nilfs->ns_sbh[0]);                 
575         nilfs->ns_sbh[0] = nilfs->ns_sbh[1];      
576         nilfs->ns_sbp[0] = nilfs->ns_sbp[1];      
577         nilfs->ns_sbh[1] = NULL;                  
578         nilfs->ns_sbp[1] = NULL;                  
579 }                                                 
580                                                   
581 void nilfs_swap_super_block(struct the_nilfs *    
582 {                                                 
583         struct buffer_head *tsbh = nilfs->ns_s    
584         struct nilfs_super_block *tsbp = nilfs    
585                                                   
586         nilfs->ns_sbh[0] = nilfs->ns_sbh[1];      
587         nilfs->ns_sbp[0] = nilfs->ns_sbp[1];      
588         nilfs->ns_sbh[1] = tsbh;                  
589         nilfs->ns_sbp[1] = tsbp;                  
590 }                                                 
591                                                   
592 static int nilfs_load_super_block(struct the_n    
593                                   struct super    
594                                   struct nilfs    
595 {                                                 
596         struct nilfs_super_block **sbp = nilfs    
597         struct buffer_head **sbh = nilfs->ns_s    
598         u64 sb2off, devsize = bdev_nr_bytes(ni    
599         int valid[2], swp = 0, older;             
600                                                   
601         if (devsize < NILFS_SEG_MIN_BLOCKS * N    
602                 nilfs_err(sb, "device size too    
603                 return -EINVAL;                   
604         }                                         
605         sb2off = NILFS_SB2_OFFSET_BYTES(devsiz    
606                                                   
607         sbp[0] = nilfs_read_super_block(sb, NI    
608                                         &sbh[0    
609         sbp[1] = nilfs_read_super_block(sb, sb    
610                                                   
611         if (!sbp[0]) {                            
612                 if (!sbp[1]) {                    
613                         nilfs_err(sb, "unable     
614                         return -EIO;              
615                 }                                 
616                 nilfs_warn(sb,                    
617                            "unable to read pri    
618                            blocksize);            
619         } else if (!sbp[1]) {                     
620                 nilfs_warn(sb,                    
621                            "unable to read sec    
622                            blocksize);            
623         }                                         
624                                                   
625         /*                                        
626          * Compare two super blocks and set 1     
627          * super block is valid and newer.  Ot    
628          */                                       
629         valid[0] = nilfs_valid_sb(sbp[0]);        
630         valid[1] = nilfs_valid_sb(sbp[1]);        
631         swp = valid[1] && (!valid[0] ||           
632                            le64_to_cpu(sbp[1]-    
633                            le64_to_cpu(sbp[0]-    
634                                                   
635         if (valid[swp] && nilfs_sb2_bad_offset    
636                 brelse(sbh[1]);                   
637                 sbh[1] = NULL;                    
638                 sbp[1] = NULL;                    
639                 valid[1] = 0;                     
640                 swp = 0;                          
641         }                                         
642         if (!valid[swp]) {                        
643                 nilfs_release_super_block(nilf    
644                 nilfs_err(sb, "couldn't find n    
645                 return -EINVAL;                   
646         }                                         
647                                                   
648         if (!valid[!swp])                         
649                 nilfs_warn(sb,                    
650                            "broken superblock,    
651                            blocksize);            
652         if (swp)                                  
653                 nilfs_swap_super_block(nilfs);    
654                                                   
655         /*                                        
656          * Calculate the array index of the ol    
657          * If one has been dropped, set index     
658          * otherwise set index 1 pointing to t    
659          * are the same).                         
660          *                                        
661          *  Divided case             valid[0]     
662          *  ----------------------------------    
663          *  Both SBs are invalid        0         
664          *  SB1 is invalid              0         
665          *  SB2 is invalid              1         
666          *  SB2 is newer                1         
667          *  SB2 is older or the same    1         
668          */                                       
669         older = valid[1] ^ swp;                   
670                                                   
671         nilfs->ns_sbwcount = 0;                   
672         nilfs->ns_sbwtime = le64_to_cpu(sbp[0]    
673         nilfs->ns_prot_seq = le64_to_cpu(sbp[o    
674         *sbpp = sbp[0];                           
675         return 0;                                 
676 }                                                 
677                                                   
678 /**                                               
679  * init_nilfs - initialize a NILFS instance.      
680  * @nilfs: the_nilfs structure                    
681  * @sb: super block                               
682  *                                                
683  * init_nilfs() performs common initialization    
684  * reading the super block, getting disk layou    
685  * shared fields in the_nilfs).                   
686  *                                                
687  * Return Value: On success, 0 is returned. On    
688  * code is returned.                              
689  */                                               
690 int init_nilfs(struct the_nilfs *nilfs, struct    
691 {                                                 
692         struct nilfs_super_block *sbp;            
693         int blocksize;                            
694         int err;                                  
695                                                   
696         down_write(&nilfs->ns_sem);               
697                                                   
698         blocksize = sb_min_blocksize(sb, NILFS    
699         if (!blocksize) {                         
700                 nilfs_err(sb, "unable to set b    
701                 err = -EINVAL;                    
702                 goto out;                         
703         }                                         
704         err = nilfs_load_super_block(nilfs, sb    
705         if (err)                                  
706                 goto out;                         
707                                                   
708         err = nilfs_store_magic(sb, sbp);         
709         if (err)                                  
710                 goto failed_sbh;                  
711                                                   
712         err = nilfs_check_feature_compatibilit    
713         if (err)                                  
714                 goto failed_sbh;                  
715                                                   
716         err = nilfs_get_blocksize(sb, sbp, &bl    
717         if (err)                                  
718                 goto failed_sbh;                  
719                                                   
720         if (blocksize < NILFS_MIN_BLOCK_SIZE)     
721                 nilfs_err(sb,                     
722                           "couldn't mount beca    
723                           blocksize);             
724                 err = -EINVAL;                    
725                 goto failed_sbh;                  
726         }                                         
727         if (sb->s_blocksize != blocksize) {       
728                 int hw_blocksize = bdev_logica    
729                                                   
730                 if (blocksize < hw_blocksize)     
731                         nilfs_err(sb,             
732                                   "blocksize %    
733                                   blocksize, h    
734                         err = -EINVAL;            
735                         goto failed_sbh;          
736                 }                                 
737                 nilfs_release_super_block(nilf    
738                 if (!sb_set_blocksize(sb, bloc    
739                         nilfs_err(sb, "bad blo    
740                         err = -EINVAL;            
741                         goto out;                 
742                 }                                 
743                                                   
744                 err = nilfs_load_super_block(n    
745                 if (err)                          
746                         goto out;                 
747                         /*                        
748                          * Not to failed_sbh;     
749                          * when reloading fail    
750                          */                       
751         }                                         
752         nilfs->ns_blocksize_bits = sb->s_block    
753         nilfs->ns_blocksize = blocksize;          
754                                                   
755         err = nilfs_store_disk_layout(nilfs, s    
756         if (err)                                  
757                 goto failed_sbh;                  
758                                                   
759         sb->s_maxbytes = nilfs_max_size(sb->s_    
760                                                   
761         nilfs->ns_mount_state = le16_to_cpu(sb    
762                                                   
763         err = nilfs_store_log_cursor(nilfs, sb    
764         if (err)                                  
765                 goto failed_sbh;                  
766                                                   
767         set_nilfs_init(nilfs);                    
768         err = 0;                                  
769  out:                                             
770         up_write(&nilfs->ns_sem);                 
771         return err;                               
772                                                   
773  failed_sbh:                                      
774         nilfs_release_super_block(nilfs);         
775         goto out;                                 
776 }                                                 
777                                                   
778 int nilfs_discard_segments(struct the_nilfs *n    
779                             size_t nsegs)         
780 {                                                 
781         sector_t seg_start, seg_end;              
782         sector_t start = 0, nblocks = 0;          
783         unsigned int sects_per_block;             
784         __u64 *sn;                                
785         int ret = 0;                              
786                                                   
787         sects_per_block = (1 << nilfs->ns_bloc    
788                 bdev_logical_block_size(nilfs-    
789         for (sn = segnump; sn < segnump + nseg    
790                 nilfs_get_segment_range(nilfs,    
791                                                   
792                 if (!nblocks) {                   
793                         start = seg_start;        
794                         nblocks = seg_end - se    
795                 } else if (start + nblocks ==     
796                         nblocks += seg_end - s    
797                 } else {                          
798                         ret = blkdev_issue_dis    
799                                                   
800                                                   
801                                                   
802                         if (ret < 0)              
803                                 return ret;       
804                         nblocks = 0;              
805                 }                                 
806         }                                         
807         if (nblocks)                              
808                 ret = blkdev_issue_discard(nil    
809                                            sta    
810                                            nbl    
811                                            GFP    
812         return ret;                               
813 }                                                 
814                                                   
815 int nilfs_count_free_blocks(struct the_nilfs *    
816 {                                                 
817         unsigned long ncleansegs;                 
818                                                   
819         ncleansegs = nilfs_sufile_get_ncleanse    
820         *nblocks = (sector_t)ncleansegs * nilf    
821         return 0;                                 
822 }                                                 
823                                                   
824 int nilfs_near_disk_full(struct the_nilfs *nil    
825 {                                                 
826         unsigned long ncleansegs, nincsegs;       
827                                                   
828         ncleansegs = nilfs_sufile_get_ncleanse    
829         nincsegs = atomic_read(&nilfs->ns_ndir    
830                 nilfs->ns_blocks_per_segment +    
831                                                   
832         return ncleansegs <= nilfs->ns_nrsvseg    
833 }                                                 
834                                                   
835 struct nilfs_root *nilfs_lookup_root(struct th    
836 {                                                 
837         struct rb_node *n;                        
838         struct nilfs_root *root;                  
839                                                   
840         spin_lock(&nilfs->ns_cptree_lock);        
841         n = nilfs->ns_cptree.rb_node;             
842         while (n) {                               
843                 root = rb_entry(n, struct nilf    
844                                                   
845                 if (cno < root->cno) {            
846                         n = n->rb_left;           
847                 } else if (cno > root->cno) {     
848                         n = n->rb_right;          
849                 } else {                          
850                         refcount_inc(&root->co    
851                         spin_unlock(&nilfs->ns    
852                         return root;              
853                 }                                 
854         }                                         
855         spin_unlock(&nilfs->ns_cptree_lock);      
856                                                   
857         return NULL;                              
858 }                                                 
859                                                   
860 struct nilfs_root *                               
861 nilfs_find_or_create_root(struct the_nilfs *ni    
862 {                                                 
863         struct rb_node **p, *parent;              
864         struct nilfs_root *root, *new;            
865         int err;                                  
866                                                   
867         root = nilfs_lookup_root(nilfs, cno);     
868         if (root)                                 
869                 return root;                      
870                                                   
871         new = kzalloc(sizeof(*root), GFP_KERNE    
872         if (!new)                                 
873                 return NULL;                      
874                                                   
875         spin_lock(&nilfs->ns_cptree_lock);        
876                                                   
877         p = &nilfs->ns_cptree.rb_node;            
878         parent = NULL;                            
879                                                   
880         while (*p) {                              
881                 parent = *p;                      
882                 root = rb_entry(parent, struct    
883                                                   
884                 if (cno < root->cno) {            
885                         p = &(*p)->rb_left;       
886                 } else if (cno > root->cno) {     
887                         p = &(*p)->rb_right;      
888                 } else {                          
889                         refcount_inc(&root->co    
890                         spin_unlock(&nilfs->ns    
891                         kfree(new);               
892                         return root;              
893                 }                                 
894         }                                         
895                                                   
896         new->cno = cno;                           
897         new->ifile = NULL;                        
898         new->nilfs = nilfs;                       
899         refcount_set(&new->count, 1);             
900         atomic64_set(&new->inodes_count, 0);      
901         atomic64_set(&new->blocks_count, 0);      
902                                                   
903         rb_link_node(&new->rb_node, parent, p)    
904         rb_insert_color(&new->rb_node, &nilfs-    
905                                                   
906         spin_unlock(&nilfs->ns_cptree_lock);      
907                                                   
908         err = nilfs_sysfs_create_snapshot_grou    
909         if (err) {                                
910                 kfree(new);                       
911                 new = NULL;                       
912         }                                         
913                                                   
914         return new;                               
915 }                                                 
916                                                   
917 void nilfs_put_root(struct nilfs_root *root)      
918 {                                                 
919         struct the_nilfs *nilfs = root->nilfs;    
920                                                   
921         if (refcount_dec_and_lock(&root->count    
922                 rb_erase(&root->rb_node, &nilf    
923                 spin_unlock(&nilfs->ns_cptree_    
924                                                   
925                 nilfs_sysfs_delete_snapshot_gr    
926                 iput(root->ifile);                
927                                                   
928                 kfree(root);                      
929         }                                         
930 }                                                 
931                                                   

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