Thread (10 messages) 10 messages, 2 authors, 2021-06-16

Re: [PATCH v2 3/4] pstore/blk: Include zone in pstore_device_info

From: Kees Cook <hidden>
Date: 2021-06-16 14:42:02
Also in: linux-block, linux-fsdevel, lkml

On Wed, Jun 16, 2021 at 06:02:47AM +0200, Christoph Hellwig wrote:
quoted
+#define verify_size(name, alignsize, enabled) {				\
+		long _##name_;						\
+		if (enabled)						\
+			_##name_ = check_size(name, alignsize);		\
+		else							\
+			_##name_ = 0;					\
+		/* synchronize visible module parameters to result. */	\
+		name = _##name_ / 1024;					\
+		dev->zone.name = _##name_;				\
+	}
The formatting here looks weird between the two-tab indent and the
opening brace on the macro definition line.
I can adjust that, sure.
quoted
-	if (!dev || !dev->total_size || !dev->read || !dev->write) {
+	if (!dev || !dev->zone.total_size || !dev->zone.read || !dev->zone.write) {
 		if (!dev)
-			pr_err("NULL device info\n");
+			pr_err("NULL pstore_device_info\n");
 		else {
-			if (!dev->total_size)
+			if (!dev->zone.total_size)
 				pr_err("zero sized device\n");
-			if (!dev->read)
+			if (!dev->zone.read)
 				pr_err("no read handler for device\n");
-			if (!dev->write)
+			if (!dev->zone.write)
 				pr_err("no write handler for device\n");
 		}
This still looks odd to me.  Why not the somewhat more verbose but
much more obvious:

	if (!dev) {
		pr_err("NULL pstore_device_info\n");
		return -EINVAL;
	}
	if (!dev->zone.total_size) {
		pr_err("zero sized device\n");
		return -EINVAL;
	}
	...
Will do.
quoted
-	dev.total_size = i_size_read(I_BDEV(psblk_file->f_mapping->host)->bd_inode);
+	dev->zone.total_size = i_size_read(I_BDEV(psblk_file->f_mapping->host)->bd_inode);
This is starting to be unreadable long.  A local variable for the inode
might be nice, as that can also be used in the ISBLK check above.
Fair enough; will change.
quoted
+	if (!pstore_device_info && best_effort && blkdev[0]) {
+		struct pstore_device_info *best_effort_dev;
+
+		best_effort_dev = kzalloc(sizeof(*best_effort_dev), GFP_KERNEL);
+		if (!best_effort) {
+			ret = -ENOMEM;
+			goto unlock;
+		}
+		best_effort_dev->zone.read = psblk_generic_blk_read;
+		best_effort_dev->zone.write = psblk_generic_blk_write;
+
+		ret = __register_pstore_blk(best_effort_dev,
+					    early_boot_devpath(blkdev));
+		if (ret)
+			kfree(best_effort_dev);
+		else
+			pr_info("attached %s (%zu) (no dedicated panic_write!)\n",
+				blkdev, best_effort_dev->zone.total_size);
Maybe split this into a little helper?
quoted
+	/* Unregister and free the best_effort device. */
+	if (psblk_file) {
+		struct pstore_device_info *dev = pstore_device_info;
+
+		__unregister_pstore_device(dev);
+		kfree(dev);
+		fput(psblk_file);
+		psblk_file = NULL;
 	}
Same.
I guess? I don't feel strongly one way or another.
quoted
+	/* If we've been asked to unload, unregister any registered device. */
+	if (pstore_device_info)
+		__unregister_pstore_device(pstore_device_info);
Won't this double unregister pstore_device_info?
No, __unregister_pstore_device() will NULL pstore_device_info.
quoted
 struct pstore_device_info {
-	unsigned long total_size;
 	unsigned int flags;
-	pstore_zone_read_op read;
-	pstore_zone_write_op write;
-	pstore_zone_erase_op erase;
-	pstore_zone_write_op panic_write;
+	struct pstore_zone_info zone;
 };
Given that flags is only used inside of __register_pstore_device
why not kill this struct and just pass it explicitly?
Because of the mess pstore's internal APIs used to be. :) It's likely
other things will get added here in the future, and I don't want to
have to repeat the kind of argument passing games that used to exist in
this code.

-- 
Kees Cook
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help