@@ -70,7 +70,7 @@ MODULE_PARM_DESC(blkdev, "block device for pstore storage");
70
70
*/
71
71
static DEFINE_MUTEX (pstore_blk_lock );
72
72
static struct file * psblk_file ;
73
- static struct pstore_zone_info * pstore_zone_info ;
73
+ static struct pstore_device_info * pstore_device_info ;
74
74
75
75
#define check_size (name , alignsize ) ({ \
76
76
long _##name_ = (name); \
@@ -91,7 +91,7 @@ static struct pstore_zone_info *pstore_zone_info;
91
91
_##name_ = 0; \
92
92
/* Synchronize module parameters with resuls. */ \
93
93
name = _ ##name_ / 1024; \
94
- pstore_zone_info-> name = _##name_; \
94
+ dev->zone. name = _##name_; \
95
95
}
96
96
97
97
static int __register_pstore_device (struct pstore_device_info * dev )
@@ -104,50 +104,42 @@ static int __register_pstore_device(struct pstore_device_info *dev)
104
104
pr_err ("NULL device info\n" );
105
105
return - EINVAL ;
106
106
}
107
- if (!dev -> total_size ) {
107
+ if (!dev -> zone . total_size ) {
108
108
pr_err ("zero sized device\n" );
109
109
return - EINVAL ;
110
110
}
111
- if (!dev -> read ) {
111
+ if (!dev -> zone . read ) {
112
112
pr_err ("no read handler for device\n" );
113
113
return - EINVAL ;
114
114
}
115
- if (!dev -> write ) {
115
+ if (!dev -> zone . write ) {
116
116
pr_err ("no write handler for device\n" );
117
117
return - EINVAL ;
118
118
}
119
119
120
120
/* someone already registered before */
121
- if (pstore_zone_info )
121
+ if (pstore_device_info )
122
122
return - EBUSY ;
123
123
124
- pstore_zone_info = kzalloc (sizeof (struct pstore_zone_info ), GFP_KERNEL );
125
- if (!pstore_zone_info )
126
- return - ENOMEM ;
127
-
128
124
/* zero means not limit on which backends to attempt to store. */
129
125
if (!dev -> flags )
130
126
dev -> flags = UINT_MAX ;
131
127
128
+ /* Copy in module parameters. */
132
129
verify_size (kmsg_size , 4096 , dev -> flags & PSTORE_FLAGS_DMESG );
133
130
verify_size (pmsg_size , 4096 , dev -> flags & PSTORE_FLAGS_PMSG );
134
131
verify_size (console_size , 4096 , dev -> flags & PSTORE_FLAGS_CONSOLE );
135
132
verify_size (ftrace_size , 4096 , dev -> flags & PSTORE_FLAGS_FTRACE );
133
+ dev -> zone .max_reason = max_reason ;
134
+
135
+ /* Initialize required zone ownership details. */
136
+ dev -> zone .name = KBUILD_MODNAME ;
137
+ dev -> zone .owner = THIS_MODULE ;
138
+
139
+ ret = register_pstore_zone (& dev -> zone );
140
+ if (ret == 0 )
141
+ pstore_device_info = dev ;
136
142
137
- pstore_zone_info -> total_size = dev -> total_size ;
138
- pstore_zone_info -> max_reason = max_reason ;
139
- pstore_zone_info -> read = dev -> read ;
140
- pstore_zone_info -> write = dev -> write ;
141
- pstore_zone_info -> erase = dev -> erase ;
142
- pstore_zone_info -> panic_write = dev -> panic_write ;
143
- pstore_zone_info -> name = KBUILD_MODNAME ;
144
- pstore_zone_info -> owner = THIS_MODULE ;
145
-
146
- ret = register_pstore_zone (pstore_zone_info );
147
- if (ret ) {
148
- kfree (pstore_zone_info );
149
- pstore_zone_info = NULL ;
150
- }
151
143
return ret ;
152
144
}
153
145
/**
@@ -174,10 +166,9 @@ EXPORT_SYMBOL_GPL(register_pstore_device);
174
166
static void __unregister_pstore_device (struct pstore_device_info * dev )
175
167
{
176
168
lockdep_assert_held (& pstore_blk_lock );
177
- if (pstore_zone_info && pstore_zone_info -> read == dev -> read ) {
178
- unregister_pstore_zone (pstore_zone_info );
179
- kfree (pstore_zone_info );
180
- pstore_zone_info = NULL ;
169
+ if (pstore_device_info && pstore_device_info == dev ) {
170
+ unregister_pstore_zone (& dev -> zone );
171
+ pstore_device_info = NULL ;
181
172
}
182
173
}
183
174
@@ -211,12 +202,9 @@ static ssize_t psblk_generic_blk_write(const char *buf, size_t bytes,
211
202
/*
212
203
* This takes its configuration only from the module parameters now.
213
204
*/
214
- static int __register_pstore_blk (const char * devpath )
205
+ static int __register_pstore_blk (struct pstore_device_info * dev ,
206
+ const char * devpath )
215
207
{
216
- struct pstore_device_info dev = {
217
- .read = psblk_generic_blk_read ,
218
- .write = psblk_generic_blk_write ,
219
- };
220
208
struct inode * inode ;
221
209
int ret = - ENODEV ;
222
210
@@ -236,9 +224,9 @@ static int __register_pstore_blk(const char *devpath)
236
224
}
237
225
238
226
inode = I_BDEV (psblk_file -> f_mapping -> host )-> bd_inode ;
239
- dev .total_size = i_size_read (inode );
227
+ dev -> zone .total_size = i_size_read (inode );
240
228
241
- ret = __register_pstore_device (& dev );
229
+ ret = __register_pstore_device (dev );
242
230
if (ret )
243
231
goto err_fput ;
244
232
@@ -252,18 +240,6 @@ static int __register_pstore_blk(const char *devpath)
252
240
return ret ;
253
241
}
254
242
255
- static void __unregister_pstore_blk (struct file * device )
256
- {
257
- struct pstore_device_info dev = { .read = psblk_generic_blk_read };
258
-
259
- lockdep_assert_held (& pstore_blk_lock );
260
- if (psblk_file && psblk_file == device ) {
261
- __unregister_pstore_device (& dev );
262
- fput (psblk_file );
263
- psblk_file = NULL ;
264
- }
265
- }
266
-
267
243
/* get information of pstore/blk */
268
244
int pstore_blk_get_config (struct pstore_blk_config * info )
269
245
{
@@ -308,18 +284,63 @@ static inline const char *early_boot_devpath(const char *initial_devname)
308
284
}
309
285
#endif
310
286
287
+ static int __init __best_effort_init (void )
288
+ {
289
+ struct pstore_device_info * best_effort_dev ;
290
+ int ret ;
291
+
292
+ /* No best-effort mode requested. */
293
+ if (!best_effort )
294
+ return 0 ;
295
+
296
+ /* Reject an empty blkdev. */
297
+ if (!blkdev [0 ]) {
298
+ pr_err ("blkdev empty with best_effort=Y\n" );
299
+ return - EINVAL ;
300
+ }
301
+
302
+ best_effort_dev = kzalloc (sizeof (* best_effort_dev ), GFP_KERNEL );
303
+ if (!best_effort_dev )
304
+ return - ENOMEM ;
305
+
306
+ best_effort_dev -> zone .read = psblk_generic_blk_read ;
307
+ best_effort_dev -> zone .write = psblk_generic_blk_write ;
308
+
309
+ ret = __register_pstore_blk (best_effort_dev ,
310
+ early_boot_devpath (blkdev ));
311
+ if (ret )
312
+ kfree (best_effort_dev );
313
+ else
314
+ pr_info ("attached %s (%zu) (no dedicated panic_write!)\n" ,
315
+ blkdev , best_effort_dev -> zone .total_size );
316
+
317
+ return ret ;
318
+ }
319
+
320
+ static void __exit __best_effort_exit (void )
321
+ {
322
+ /*
323
+ * Currently, the only user of psblk_file is best_effort, so
324
+ * we can assume that pstore_device_info is associated with it.
325
+ * Once there are "real" blk devices, there will need to be a
326
+ * dedicated pstore_blk_info, etc.
327
+ */
328
+ if (psblk_file ) {
329
+ struct pstore_device_info * dev = pstore_device_info ;
330
+
331
+ __unregister_pstore_device (dev );
332
+ kfree (dev );
333
+ fput (psblk_file );
334
+ psblk_file = NULL ;
335
+ }
336
+ }
337
+
311
338
static int __init pstore_blk_init (void )
312
339
{
313
- int ret = 0 ;
340
+ int ret ;
314
341
315
342
mutex_lock (& pstore_blk_lock );
316
- if (!pstore_zone_info && best_effort && blkdev [0 ]) {
317
- ret = __register_pstore_blk (early_boot_devpath (blkdev ));
318
- if (ret == 0 && pstore_zone_info )
319
- pr_info ("attached %s:%s (%zu) (no dedicated panic_write!)\n" ,
320
- pstore_zone_info -> name , blkdev ,
321
- pstore_zone_info -> total_size );
322
- }
343
+ ret = __best_effort_init ();
323
344
mutex_unlock (& pstore_blk_lock );
324
345
325
346
return ret ;
@@ -329,15 +350,9 @@ late_initcall(pstore_blk_init);
329
350
static void __exit pstore_blk_exit (void )
330
351
{
331
352
mutex_lock (& pstore_blk_lock );
332
- if (psblk_file )
333
- __unregister_pstore_blk (psblk_file );
334
- else {
335
- struct pstore_device_info dev = { };
336
-
337
- if (pstore_zone_info )
338
- dev .read = pstore_zone_info -> read ;
339
- __unregister_pstore_device (& dev );
340
- }
353
+ __best_effort_exit ();
354
+ /* If we've been asked to unload, unregister any remaining device. */
355
+ __unregister_pstore_device (pstore_device_info );
341
356
mutex_unlock (& pstore_blk_lock );
342
357
}
343
358
module_exit (pstore_blk_exit );
0 commit comments