Advertisement
xosski

Binary tree manipulation

Jan 9th, 2025
7
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.58 KB | None | 0 0
  1. #include <linux/blkdev.h>
  2. #include <linux/fs.h>
  3. #include <linux/slab.h>
  4. #include <linux/dm-io.h>
  5. #include <linux/module.h>
  6. #include <linux/errno.h>
  7.  
  8. struct TreeNode {
  9. int data;
  10. struct TreeNode *left;
  11. struct TreeNode *right;
  12. };
  13.  
  14. // Function to read a sector from the block device
  15. int read_sector(struct block_device *bdev, void *buffer, unsigned long sector, unsigned int count) {
  16. struct dm_io_client *io_client;
  17. struct dm_io_region io_region;
  18. struct dm_io_request io_req;
  19. int ret;
  20.  
  21. io_client = dm_io_client_create();
  22. if (IS_ERR(io_client)) {
  23. pr_err("Failed to create I/O client\n");
  24. return PTR_ERR(io_client);
  25. }
  26.  
  27. io_region.bdev = bdev;
  28. io_region.sector = sector;
  29. io_region.count = count;
  30.  
  31. io_req.bi_op = REQ_OP_READ;
  32. io_req.client = io_client;
  33. io_req.mem.type = DM_IO_KMEM;
  34. io_req.mem.ptr.addr = buffer;
  35.  
  36. ret = dm_io(&io_req, 1, &io_region, NULL);
  37. if (ret) {
  38. pr_err("I/O read failed\n");
  39. dm_io_client_destroy(io_client);
  40. return ret;
  41. }
  42.  
  43. dm_io_client_destroy(io_client);
  44. return 0;
  45. }
  46.  
  47. // Function to write data to a sector on the block device
  48. int write_sector(struct block_device *bdev, void *buffer, unsigned long sector, unsigned int count) {
  49. struct dm_io_client *io_client;
  50. struct dm_io_region io_region;
  51. struct dm_io_request io_req;
  52. int ret;
  53.  
  54. io_client = dm_io_client_create();
  55. if (IS_ERR(io_client)) {
  56. pr_err("Failed to create I/O client\n");
  57. return PTR_ERR(io_client);
  58. }
  59.  
  60. io_region.bdev = bdev;
  61. io_region.sector = sector;
  62. io_region.count = count;
  63.  
  64. io_req.bi_op = REQ_OP_WRITE;
  65. io_req.client = io_client;
  66. io_req.mem.type = DM_IO_KMEM;
  67. io_req.mem.ptr.addr = buffer;
  68.  
  69. ret = dm_io(&io_req, 1, &io_region, NULL);
  70. if (ret) {
  71. pr_err("I/O write failed\n");
  72. dm_io_client_destroy(io_client);
  73. return ret;
  74. }
  75.  
  76. dm_io_client_destroy(io_client);
  77. return 0;
  78. }
  79.  
  80. // Function to traverse the binary tree and find the largest number
  81. int find_largest_number(struct TreeNode *root) {
  82. if (root == NULL)
  83. return INT_MIN; // Return the smallest possible integer if the node is NULL
  84.  
  85. int left_max = find_largest_number(root->left); // Recursively find in left subtree
  86. int right_max = find_largest_number(root->right); // Recursively find in right subtree
  87.  
  88. // Return the largest value among current node, left subtree, and right subtree
  89. return max(root->data, max(left_max, right_max));
  90. }
  91.  
  92. // Function to recursively reconstruct the binary tree from raw data in the buffer
  93. int reconstruct_tree(struct block_device *bdev, unsigned long *sector, struct TreeNode **node) {
  94. void *buffer;
  95. int ret;
  96.  
  97. // Allocate buffer for reading a sector
  98. buffer = kmalloc(4096, GFP_KERNEL);
  99. if (!buffer) {
  100. pr_err("Failed to allocate buffer\n");
  101. return -ENOMEM;
  102. }
  103.  
  104. // Read the current sector
  105. ret = read_sector(bdev, buffer, *sector, 1);
  106. if (ret) {
  107. kfree(buffer);
  108. return ret;
  109. }
  110.  
  111. // Assume each node is stored as an integer in the buffer (simplified for the example)
  112. (*node) = kmalloc(sizeof(struct TreeNode), GFP_KERNEL);
  113. if (!*node) {
  114. kfree(buffer);
  115. pr_err("Failed to allocate TreeNode\n");
  116. return -ENOMEM;
  117. }
  118.  
  119. (*node)->data = *((int *)buffer); // The first 4 bytes of the buffer are the data of the node
  120. (*node)->left = NULL;
  121. (*node)->right = NULL;
  122.  
  123. // Move to the next sector
  124. (*sector)++;
  125.  
  126. // Recursively build the left and right subtrees
  127. if ((*sector) % 2 == 0) { // Example condition for choosing left/right child for simplicity
  128. ret = reconstruct_tree(bdev, sector, &(*node)->left); // Recurse for left child
  129. if (ret) {
  130. kfree(buffer);
  131. return ret;
  132. }
  133. }
  134.  
  135. if ((*sector) % 3 == 0) {
  136. ret = reconstruct_tree(bdev, sector, &(*node)->right); // Recurse for right child
  137. if (ret) {
  138. kfree(buffer);
  139. return ret;
  140. }
  141. }
  142.  
  143. // Optionally write the current node's data to the block device
  144. ret = write_sector(bdev, &( (*node)->data), *sector - 1, 1); // Write back node's data to previous sector
  145. if (ret) {
  146. pr_err("Failed to write node data to block device\n");
  147. }
  148.  
  149. kfree(buffer);
  150. return 0;
  151. }
  152.  
  153. static int __init hello_init(void) {
  154. struct block_device *bdev;
  155. struct TreeNode *root = NULL;
  156. int largest_number;
  157. int ret;
  158. unsigned long sector = 0; // Start from the first sector
  159.  
  160. // Open the block device for reading and writing
  161. bdev = blkdev_get_by_path("/dev/sdb", FMODE_READ | FMODE_WRITE, NULL);
  162. if (IS_ERR(bdev)) {
  163. pr_err("Failed to open block device\n");
  164. return PTR_ERR(bdev);
  165. }
  166.  
  167. // Reconstruct the tree from the block device
  168. ret = reconstruct_tree(bdev, &sector, &root);
  169. if (ret) {
  170. pr_err("Failed to reconstruct tree\n");
  171. blkdev_put(bdev, FMODE_READ | FMODE_WRITE);
  172. return ret;
  173. }
  174.  
  175. // Find the largest number in the tree
  176. largest_number = find_largest_number(root);
  177. pr_info("Largest number in the tree: %d\n", largest_number);
  178.  
  179. // Clean up
  180. kfree(root); // Free the allocated tree
  181. blkdev_put(bdev, FMODE_READ | FMODE_WRITE);
  182. return 0;
  183. }
  184.  
  185. static void __exit hello_exit(void) {
  186. pr_info("Kernel module exited\n");
  187. }
  188. MODULE_INFO(intree,"Y");
  189. module_init(hello_init);
  190. module_exit(hello_exit);
  191. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement