-1

Let say I have a structure of disk_info with members devname & devno. And I have created linked list of the same. Now I want to convert this linked list to contiguous memory so as to easily pass the data to kernel through ioctl. And at the kernel side I want to again read the contiguous memory & convert to array Basically I want to convert linked list- array-linked list.

struct blkext_node {
    dev_t   devno;
    char    devname[32];
};

typedef struct blkext_disk_info {
    struct blkext_node blkext_device;
    struct blkext_disk_info *next;
} blkext_disk_info_t;

ptr1 = head_list
// Allocate the contiguous memory where total_cnt is the no of nodes in linked list
ioctl_ptr = (struct blkext_node *)malloc(total_cnt*sizeof(struct blkext_node));

for(i=0; i<total_cnt; i++) {
    if(ptr1!=NULL) {
        memcpy(ioctl_ptr + i, ptr1, sizeof(struct blkext_node));
        ptr1=ptr1->next;
    } else 
            break;

}

This is the final working code.

Nikita Kodkani
  • 165
  • 1
  • 2
  • 11

1 Answers1

3

This is the general procedure:

  1. walk the list to determine its length
  2. allocate an array with a suitable size
  3. walk the list another time and copy each item to a slot in the array.

This procedure is good enough for most purposes but prone to a race condition when another thread changes the list after step (1) and before step (3) has finished.

Now for your specific question, the loop body should be replaced by something like this:

bcopy(&ptr1->blkext_device, ioctl_ptr + i, sizeof(struct blkext_node));
ptr1 = ptr1->next;

Consider checking if ptr1 != NULL in the loop head, too, to at least not crash the kernel in case of a race condition.

fuz
  • 88,405
  • 25
  • 200
  • 352