I never found the definition for scull_follow in the book, so I'm trying to understand it based off a github repo(https://github.com/martinezjavier/ldd3).Here is the code I am trying to understand:
struct scull_qset *scull_follow(struct scull_dev *dev, int n) { struct scull_qset *qs = dev->data; /* Allocate first qset explicitly if need be */ if (!qs) { // if NULL qs = dev->data = kmalloc(sizeof(struct scull_qset), GFP_KERNEL); if (qs == NULL) return NULL; /* Never mind */ memset(qs, 0, sizeof(struct scull_qset)); } /* Then follow the list */ while (n--) { if (!qs->next) { qs->next = kmalloc(sizeof(struct scull_qset), GFP_KERNEL); if (qs->next == NULL) return NULL; /* Never mind */ memset(qs->next, 0, sizeof(struct scull_qset)); } qs = qs->next; continue; } return qs;}
Here is struct scull_qset
:
struct scull_qset { void **data; struct scull_qset *next;};
Conceptually, I understand that all scull_follow
does is that it follows the list up to the right position so that you know where to start reading/writing.I'm mainly confused on this part of the code.
/* Allocate first qset explicitly if need be */ if (!qs) { // if NULL qs = dev->data = kmalloc(sizeof(struct scull_qset), GFP_KERNEL); if (qs == NULL) return NULL; /* Never mind */ memset(qs, 0, sizeof(struct scull_qset)); }
Let's say the user opens this driver and attempts to read from it first without writing. that should mean that it should go into the if statement and allocate some memory. Then, why is there a second check for if qs
is NULL
or not? Won't it always be not NULL because it was allocated some memory?
After that what is the memset
function for? I understand that it copies 0 into qs
, but what is the point of that other than initializing this memory region? Is it so that when you call the copy_to_user
function in your read function it'll know that because it is filled with 0s, nothing of 'value' has been written to it so you will just get a blank output when reading, assuming the first operation you do is reading?
Thanks for answering my questions.