From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 1/2] cdev: pass master cdev to cdev ops
Date: Mon, 02 Jun 2025 10:51:31 +0200 [thread overview]
Message-ID: <20250602-cdev-part-fixes-v1-1-814d9aa195ed@pengutronix.de> (raw)
In-Reply-To: <20250602-cdev-part-fixes-v1-0-814d9aa195ed@pengutronix.de>
cdev partitions are cdevs themselves, but they are handled internally in
the devfs-core. cdev partitions should not be passed as context pointers
to the cdev ops though, because the drivers might do a container_of() on
them to retrieve their driver data. Pass the original cdev the driver
has registered as context to the ops. With this we can drop some quirks
in the nvmem core in the next step.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
fs/devfs-core.c | 53 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 41 insertions(+), 12 deletions(-)
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 5fafcaecc70d63287e0b716cc0133198c28e79e9..73a13be7336df1eb4e24e8a936986b6069f3783c 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -224,12 +224,21 @@ int cdev_find_free_index(const char *basename)
return -EBUSY; /* all indexes are used */
}
+static struct cdev *cdev_get_master(struct cdev *cdev)
+{
+ while (cdev && cdev_is_partition(cdev))
+ cdev = cdev->master;
+
+ return cdev;
+}
+
int cdev_open(struct cdev *cdev, unsigned long flags)
{
+ struct cdev *master = cdev_get_master(cdev);
int ret;
if (cdev->ops->open) {
- ret = cdev->ops->open(cdev, flags);
+ ret = cdev->ops->open(master, flags);
if (ret)
return ret;
}
@@ -275,8 +284,10 @@ struct cdev *cdev_open_by_name(const char *name, unsigned long flags)
int cdev_close(struct cdev *cdev)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (cdev->ops->close) {
- int ret = cdev->ops->close(cdev);
+ int ret = cdev->ops->close(master);
if (ret)
return ret;
}
@@ -288,50 +299,61 @@ int cdev_close(struct cdev *cdev)
ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (!cdev->ops->read)
return -ENOSYS;
- return cdev->ops->read(cdev, buf, count, cdev->offset +offset, flags);
+ return cdev->ops->read(master, buf, count, cdev->offset +offset, flags);
}
ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (!cdev->ops->write)
return -ENOSYS;
- return cdev->ops->write(cdev, buf, count, cdev->offset + offset, flags);
+ return cdev->ops->write(master, buf, count, cdev->offset + offset, flags);
}
int cdev_flush(struct cdev *cdev)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (!cdev->ops->flush)
return 0;
- return cdev->ops->flush(cdev);
+ return cdev->ops->flush(master);
}
int cdev_ioctl(struct cdev *cdev, unsigned int request, void *buf)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (!cdev->ops->ioctl)
return -EINVAL;
- return cdev->ops->ioctl(cdev, request, buf);
+ return cdev->ops->ioctl(master, request, buf);
}
int cdev_erase(struct cdev *cdev, loff_t count, loff_t offset)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (!cdev->ops->erase)
return -ENOSYS;
- return cdev->ops->erase(cdev, count, cdev->offset + offset);
+ return cdev->ops->erase(master, count, cdev->offset + offset);
}
int cdev_lseek(struct cdev *cdev, loff_t pos)
{
+ struct cdev *master = cdev_get_master(cdev);
int ret;
if (cdev->ops->lseek) {
- ret = cdev->ops->lseek(cdev, pos + cdev->offset);
+ ret = cdev->ops->lseek(master, pos + cdev->offset);
if (ret < 0)
return ret;
}
@@ -341,14 +363,18 @@ int cdev_lseek(struct cdev *cdev, loff_t pos)
int cdev_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (!cdev->ops->protect)
return -ENOSYS;
- return cdev->ops->protect(cdev, count, offset + cdev->offset, prot);
+ return cdev->ops->protect(master, count, offset + cdev->offset, prot);
}
int cdev_discard_range(struct cdev *cdev, loff_t count, loff_t offset)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (!cdev->ops->discard_range)
return -ENOSYS;
@@ -361,17 +387,18 @@ int cdev_discard_range(struct cdev *cdev, loff_t count, loff_t offset)
if (count + offset > cdev->size)
count = cdev->size - offset;
- return cdev->ops->discard_range(cdev, count, offset + cdev->offset);
+ return cdev->ops->discard_range(master, count, offset + cdev->offset);
}
int cdev_memmap(struct cdev *cdev, void **map, int flags)
{
+ struct cdev *master = cdev_get_master(cdev);
int ret = -ENOSYS;
if (!cdev->ops->memmap)
return -EINVAL;
- ret = cdev->ops->memmap(cdev, map, flags);
+ ret = cdev->ops->memmap(master, map, flags);
if (!ret)
*map = (void *)((unsigned long)*map + (unsigned long)cdev->offset);
@@ -381,8 +408,10 @@ int cdev_memmap(struct cdev *cdev, void **map, int flags)
int cdev_truncate(struct cdev *cdev, size_t size)
{
+ struct cdev *master = cdev_get_master(cdev);
+
if (cdev->ops->truncate)
- return cdev->ops->truncate(cdev, size);
+ return cdev->ops->truncate(master, size);
return -EPERM;
}
--
2.39.5
next prev parent reply other threads:[~2025-06-02 8:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-02 8:51 [PATCH 0/2] cdev partition fix Sascha Hauer
2025-06-02 8:51 ` Sascha Hauer [this message]
2025-06-02 9:03 ` [PATCH 1/2] cdev: pass master cdev to cdev ops Ahmad Fatoum
2025-06-02 10:12 ` Sascha Hauer
2025-06-02 10:20 ` Ahmad Fatoum
2025-06-02 8:51 ` [PATCH 2/2] nvmem: Drop now unnecessary partition quirk Sascha Hauer
2025-06-02 12:30 ` [PATCH 0/2] cdev partition fix Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250602-cdev-part-fixes-v1-1-814d9aa195ed@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox