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

TOMOYO Linux Cross Reference
Linux/fs/pstore/inode.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/pstore/inode.c (Version linux-6.12-rc7) and /fs/pstore/inode.c (Version linux-2.6.32.71)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * Persistent Storage - ramfs parts.              
  4  *                                                
  5  * Copyright (C) 2010 Intel Corporation <tony.    
  6  */                                               
  7                                                   
  8 #include <linux/module.h>                         
  9 #include <linux/fs.h>                             
 10 #include <linux/fsnotify.h>                       
 11 #include <linux/pagemap.h>                        
 12 #include <linux/highmem.h>                        
 13 #include <linux/time.h>                           
 14 #include <linux/init.h>                           
 15 #include <linux/list.h>                           
 16 #include <linux/string.h>                         
 17 #include <linux/mount.h>                          
 18 #include <linux/seq_file.h>                       
 19 #include <linux/ramfs.h>                          
 20 #include <linux/parser.h>                         
 21 #include <linux/sched.h>                          
 22 #include <linux/magic.h>                          
 23 #include <linux/pstore.h>                         
 24 #include <linux/slab.h>                           
 25 #include <linux/uaccess.h>                        
 26 #include <linux/cleanup.h>                        
 27                                                   
 28 #include "internal.h"                             
 29                                                   
 30 #define PSTORE_NAMELEN  64                        
 31                                                   
 32 static DEFINE_MUTEX(records_list_lock);           
 33 static LIST_HEAD(records_list);                   
 34                                                   
 35 static DEFINE_MUTEX(pstore_sb_lock);              
 36 static struct super_block *pstore_sb;             
 37                                                   
 38 DEFINE_FREE(pstore_iput, struct inode *, if (_    
 39                                                   
 40 struct pstore_private {                           
 41         struct list_head list;                    
 42         struct dentry *dentry;                    
 43         struct pstore_record *record;             
 44         size_t total_size;                        
 45 };                                                
 46                                                   
 47 struct pstore_ftrace_seq_data {                   
 48         const void *ptr;                          
 49         size_t off;                               
 50         size_t size;                              
 51 };                                                
 52                                                   
 53 #define REC_SIZE sizeof(struct pstore_ftrace_r    
 54                                                   
 55 static void free_pstore_private(struct pstore_    
 56 {                                                 
 57         if (!private)                             
 58                 return;                           
 59         if (private->record) {                    
 60                 kvfree(private->record->buf);     
 61                 kfree(private->record->priv);     
 62                 kfree(private->record);           
 63         }                                         
 64         kfree(private);                           
 65 }                                                 
 66 DEFINE_FREE(pstore_private, struct pstore_priv    
 67                                                   
 68 static void *pstore_ftrace_seq_start(struct se    
 69 {                                                 
 70         struct pstore_private *ps = s->private    
 71         struct pstore_ftrace_seq_data *data __    
 72                                                   
 73         data = kzalloc(sizeof(*data), GFP_KERN    
 74         if (!data)                                
 75                 return NULL;                      
 76                                                   
 77         data->off = ps->total_size % REC_SIZE;    
 78         data->off += *pos * REC_SIZE;             
 79         if (data->off + REC_SIZE > ps->total_s    
 80                 return NULL;                      
 81                                                   
 82         return_ptr(data);                         
 83 }                                                 
 84                                                   
 85 static void pstore_ftrace_seq_stop(struct seq_    
 86 {                                                 
 87         kfree(v);                                 
 88 }                                                 
 89                                                   
 90 static void *pstore_ftrace_seq_next(struct seq    
 91 {                                                 
 92         struct pstore_private *ps = s->private    
 93         struct pstore_ftrace_seq_data *data =     
 94                                                   
 95         (*pos)++;                                 
 96         data->off += REC_SIZE;                    
 97         if (data->off + REC_SIZE > ps->total_s    
 98                 return NULL;                      
 99                                                   
100         return data;                              
101 }                                                 
102                                                   
103 static int pstore_ftrace_seq_show(struct seq_f    
104 {                                                 
105         struct pstore_private *ps = s->private    
106         struct pstore_ftrace_seq_data *data =     
107         struct pstore_ftrace_record *rec;         
108                                                   
109         if (!data)                                
110                 return 0;                         
111                                                   
112         rec = (struct pstore_ftrace_record *)(    
113                                                   
114         seq_printf(s, "CPU:%d ts:%llu %08lx  %    
115                    pstore_ftrace_decode_cpu(re    
116                    pstore_ftrace_read_timestam    
117                    rec->ip, rec->parent_ip, (v    
118                    (void *)rec->parent_ip);       
119                                                   
120         return 0;                                 
121 }                                                 
122                                                   
123 static const struct seq_operations pstore_ftra    
124         .start  = pstore_ftrace_seq_start,        
125         .next   = pstore_ftrace_seq_next,         
126         .stop   = pstore_ftrace_seq_stop,         
127         .show   = pstore_ftrace_seq_show,         
128 };                                                
129                                                   
130 static ssize_t pstore_file_read(struct file *f    
131                                                   
132 {                                                 
133         struct seq_file *sf = file->private_da    
134         struct pstore_private *ps = sf->privat    
135                                                   
136         if (ps->record->type == PSTORE_TYPE_FT    
137                 return seq_read(file, userbuf,    
138         return simple_read_from_buffer(userbuf    
139                                        ps->rec    
140 }                                                 
141                                                   
142 static int pstore_file_open(struct inode *inod    
143 {                                                 
144         struct pstore_private *ps = inode->i_p    
145         struct seq_file *sf;                      
146         int err;                                  
147         const struct seq_operations *sops = NU    
148                                                   
149         if (ps->record->type == PSTORE_TYPE_FT    
150                 sops = &pstore_ftrace_seq_ops;    
151                                                   
152         err = seq_open(file, sops);               
153         if (err < 0)                              
154                 return err;                       
155                                                   
156         sf = file->private_data;                  
157         sf->private = ps;                         
158                                                   
159         return 0;                                 
160 }                                                 
161                                                   
162 static loff_t pstore_file_llseek(struct file *    
163 {                                                 
164         struct seq_file *sf = file->private_da    
165                                                   
166         if (sf->op)                               
167                 return seq_lseek(file, off, wh    
168         return default_llseek(file, off, whenc    
169 }                                                 
170                                                   
171 static const struct file_operations pstore_fil    
172         .open           = pstore_file_open,       
173         .read           = pstore_file_read,       
174         .llseek         = pstore_file_llseek,     
175         .release        = seq_release,            
176 };                                                
177                                                   
178 /*                                                
179  * When a file is unlinked from our file syste    
180  * platform driver to erase the record from pe    
181  */                                               
182 static int pstore_unlink(struct inode *dir, st    
183 {                                                 
184         struct pstore_private *p = d_inode(den    
185         struct pstore_record *record = p->reco    
186                                                   
187         if (!record->psi->erase)                  
188                 return -EPERM;                    
189                                                   
190         /* Make sure we can't race while remov    
191         scoped_guard(mutex, &records_list_lock    
192                 if (!list_empty(&p->list))        
193                         list_del_init(&p->list    
194                 else                              
195                         return -ENOENT;           
196                 p->dentry = NULL;                 
197         }                                         
198                                                   
199         scoped_guard(mutex, &record->psi->read    
200                 record->psi->erase(record);       
201                                                   
202         return simple_unlink(dir, dentry);        
203 }                                                 
204                                                   
205 static void pstore_evict_inode(struct inode *i    
206 {                                                 
207         struct pstore_private   *p = inode->i_    
208                                                   
209         clear_inode(inode);                       
210         free_pstore_private(p);                   
211 }                                                 
212                                                   
213 static const struct inode_operations pstore_di    
214         .lookup         = simple_lookup,          
215         .unlink         = pstore_unlink,          
216 };                                                
217                                                   
218 static struct inode *pstore_get_inode(struct s    
219 {                                                 
220         struct inode *inode = new_inode(sb);      
221         if (inode) {                              
222                 inode->i_ino = get_next_ino();    
223                 simple_inode_init_ts(inode);      
224         }                                         
225         return inode;                             
226 }                                                 
227                                                   
228 enum {                                            
229         Opt_kmsg_bytes, Opt_err                   
230 };                                                
231                                                   
232 static const match_table_t tokens = {             
233         {Opt_kmsg_bytes, "kmsg_bytes=%u"},        
234         {Opt_err, NULL}                           
235 };                                                
236                                                   
237 static void parse_options(char *options)          
238 {                                                 
239         char            *p;                       
240         substring_t     args[MAX_OPT_ARGS];       
241         int             option;                   
242                                                   
243         if (!options)                             
244                 return;                           
245                                                   
246         while ((p = strsep(&options, ",")) !=     
247                 int token;                        
248                                                   
249                 if (!*p)                          
250                         continue;                 
251                                                   
252                 token = match_token(p, tokens,    
253                 switch (token) {                  
254                 case Opt_kmsg_bytes:              
255                         if (!match_int(&args[0    
256                                 pstore_set_kms    
257                         break;                    
258                 }                                 
259         }                                         
260 }                                                 
261                                                   
262 /*                                                
263  * Display the mount options in /proc/mounts.     
264  */                                               
265 static int pstore_show_options(struct seq_file    
266 {                                                 
267         if (kmsg_bytes != CONFIG_PSTORE_DEFAUL    
268                 seq_printf(m, ",kmsg_bytes=%lu    
269         return 0;                                 
270 }                                                 
271                                                   
272 static int pstore_remount(struct super_block *    
273 {                                                 
274         sync_filesystem(sb);                      
275         parse_options(data);                      
276                                                   
277         return 0;                                 
278 }                                                 
279                                                   
280 static const struct super_operations pstore_op    
281         .statfs         = simple_statfs,          
282         .drop_inode     = generic_delete_inode    
283         .evict_inode    = pstore_evict_inode,     
284         .remount_fs     = pstore_remount,         
285         .show_options   = pstore_show_options,    
286 };                                                
287                                                   
288 static struct dentry *psinfo_lock_root(void)      
289 {                                                 
290         struct dentry *root;                      
291                                                   
292         guard(mutex)(&pstore_sb_lock);            
293         /*                                        
294          * Having no backend is fine -- no rec    
295          * Not being mounted is fine -- nothin    
296          */                                       
297         if (!psinfo || !pstore_sb)                
298                 return NULL;                      
299                                                   
300         root = pstore_sb->s_root;                 
301         inode_lock(d_inode(root));                
302                                                   
303         return root;                              
304 }                                                 
305                                                   
306 int pstore_put_backend_records(struct pstore_i    
307 {                                                 
308         struct pstore_private *pos, *tmp;         
309         struct dentry *root;                      
310                                                   
311         root = psinfo_lock_root();                
312         if (!root)                                
313                 return 0;                         
314                                                   
315         scoped_guard(mutex, &records_list_lock    
316                 list_for_each_entry_safe(pos,     
317                         if (pos->record->psi =    
318                                 list_del_init(    
319                                 d_invalidate(p    
320                                 simple_unlink(    
321                                 pos->dentry =     
322                         }                         
323                 }                                 
324         }                                         
325                                                   
326         inode_unlock(d_inode(root));              
327                                                   
328         return 0;                                 
329 }                                                 
330                                                   
331 /*                                                
332  * Make a regular file in the root directory o    
333  * Load it up with "size" bytes of data from "    
334  * Set the mtime & ctime to the date that this    
335  */                                               
336 int pstore_mkfile(struct dentry *root, struct     
337 {                                                 
338         struct dentry           *dentry;          
339         struct inode            *inode __free(    
340         char                    name[PSTORE_NA    
341         struct pstore_private   *private __fre    
342         size_t                  size = record-    
343                                                   
344         if (WARN_ON(!inode_is_locked(d_inode(r    
345                 return -EINVAL;                   
346                                                   
347         guard(mutex)(&records_list_lock);         
348                                                   
349         /* Skip records that are already prese    
350         list_for_each_entry(pos, &records_list    
351                 if (pos->record->type == recor    
352                     pos->record->id == record-    
353                     pos->record->psi == record    
354                         return -EEXIST;           
355         }                                         
356                                                   
357         inode = pstore_get_inode(root->d_sb);     
358         if (!inode)                               
359                 return -ENOMEM;                   
360         inode->i_mode = S_IFREG | 0444;           
361         inode->i_fop = &pstore_file_operations    
362         scnprintf(name, sizeof(name), "%s-%s-%    
363                         pstore_type_to_name(re    
364                         record->psi->name, rec    
365                         record->compressed ? "    
366                                                   
367         private = kzalloc(sizeof(*private), GF    
368         if (!private)                             
369                 return -ENOMEM;                   
370                                                   
371         dentry = d_alloc_name(root, name);        
372         if (!dentry)                              
373                 return -ENOMEM;                   
374                                                   
375         private->dentry = dentry;                 
376         private->record = record;                 
377         inode->i_size = private->total_size =     
378         inode->i_private = private;               
379                                                   
380         if (record->time.tv_sec)                  
381                 inode_set_mtime_to_ts(inode,      
382                                       inode_se    
383                                                   
384         d_add(dentry, no_free_ptr(inode));        
385                                                   
386         list_add(&(no_free_ptr(private))->list    
387                                                   
388         return 0;                                 
389 }                                                 
390                                                   
391 /*                                                
392  * Read all the records from the persistent st    
393  * files in our filesystem.  Don't warn about     
394  * when we are re-scanning the backing store l    
395  * error records.                                 
396  */                                               
397 void pstore_get_records(int quiet)                
398 {                                                 
399         struct dentry *root;                      
400                                                   
401         root = psinfo_lock_root();                
402         if (!root)                                
403                 return;                           
404                                                   
405         pstore_get_backend_records(psinfo, roo    
406         inode_unlock(d_inode(root));              
407 }                                                 
408                                                   
409 static int pstore_fill_super(struct super_bloc    
410 {                                                 
411         struct inode *inode;                      
412                                                   
413         sb->s_maxbytes          = MAX_LFS_FILE    
414         sb->s_blocksize         = PAGE_SIZE;      
415         sb->s_blocksize_bits    = PAGE_SHIFT;     
416         sb->s_magic             = PSTOREFS_MAG    
417         sb->s_op                = &pstore_ops;    
418         sb->s_time_gran         = 1;              
419                                                   
420         parse_options(data);                      
421                                                   
422         inode = pstore_get_inode(sb);             
423         if (inode) {                              
424                 inode->i_mode = S_IFDIR | 0750    
425                 inode->i_op = &pstore_dir_inod    
426                 inode->i_fop = &simple_dir_ope    
427                 inc_nlink(inode);                 
428         }                                         
429         sb->s_root = d_make_root(inode);          
430         if (!sb->s_root)                          
431                 return -ENOMEM;                   
432                                                   
433         scoped_guard(mutex, &pstore_sb_lock)      
434                 pstore_sb = sb;                   
435                                                   
436         pstore_get_records(0);                    
437                                                   
438         return 0;                                 
439 }                                                 
440                                                   
441 static struct dentry *pstore_mount(struct file    
442         int flags, const char *dev_name, void     
443 {                                                 
444         return mount_single(fs_type, flags, da    
445 }                                                 
446                                                   
447 static void pstore_kill_sb(struct super_block     
448 {                                                 
449         guard(mutex)(&pstore_sb_lock);            
450         WARN_ON(pstore_sb && pstore_sb != sb);    
451                                                   
452         kill_litter_super(sb);                    
453         pstore_sb = NULL;                         
454                                                   
455         guard(mutex)(&records_list_lock);         
456         INIT_LIST_HEAD(&records_list);            
457 }                                                 
458                                                   
459 static struct file_system_type pstore_fs_type     
460         .owner          = THIS_MODULE,            
461         .name           = "pstore",               
462         .mount          = pstore_mount,           
463         .kill_sb        = pstore_kill_sb,         
464 };                                                
465                                                   
466 int __init pstore_init_fs(void)                   
467 {                                                 
468         int err;                                  
469                                                   
470         /* Create a convenient mount point for    
471         err = sysfs_create_mount_point(fs_kobj    
472         if (err)                                  
473                 goto out;                         
474                                                   
475         err = register_filesystem(&pstore_fs_t    
476         if (err < 0)                              
477                 sysfs_remove_mount_point(fs_ko    
478                                                   
479 out:                                              
480         return err;                               
481 }                                                 
482                                                   
483 void __exit pstore_exit_fs(void)                  
484 {                                                 
485         unregister_filesystem(&pstore_fs_type)    
486         sysfs_remove_mount_point(fs_kobj, "pst    
487 }                                                 
488                                                   

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