Messages in this thread | | | Date | Wed, 27 Oct 1999 04:08:41 -0700 (PDT) | From | Murray Stokely <> | Subject | filp->private_data problems |
| |
I'm having some trouble using the private_data member of the file structure in kernel modules. Below is a minimal code segment that illustrates my problem. I'm allocating space for filp->private_data in the open method, I can use the space I allocated later on in the open method, but whenever the next method gets invoked (such as a read or write) filp->private_data just points to a random location in memory instead of the memory that was allocated to it and used fine a few milliseconds earlier in the open method. Is there a fundamental misconception someone can point out to me here? I apologize if there is another mailing list dedicated more specifically to driver development but I could not find one listed on www.linux.org. Thanks for any pointers.
#include <linux/module.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include <linux/mm.h> #include <linux/slab.h> #include "murray.h"
struct driver_info { int num; char *msg; };
/* * Register any facilities offered by the module. */
int init_module(void) { printk("<1>Loading murray's misc char driver\n"); misc_register(&murray_device); return 0; }
void cleanup_module(void) { printk("<1>Unloading Murray's test char module\n"); misc_deregister(&murray_device); }
/* * Open should : check for device-specific errors * initialize the device, if being opened for the first time * identify the minor number and update the f_op pointer if necessary * allocate and fill any data structure to be put in filp->private_data * increment the usage count */ int murray_open(struct inode *inode, struct file *filp) { // struct driver_info *driv_nfo = (struct driver_info *)kmalloc(sizeof(struct driver_info),GFP_KERNEL); struct driver_info *driv_nfo = kmalloc(sizeof(struct driver_info),GFP_KERNEL); if (!driv_nfo) return -ENOMEM;
printk("<1>murray_open\n");
filp->private_data = driv_nfo; driv_nfo->msg = "hello"; driv_nfo->num = 9; printk("<1>open driv_nfo->msg : %s\n",(char *)(driv_nfo->msg)); printk("<1>open driv_nfo->num : %d\n",(int)(driv_nfo->num)); printk("<1>open filp->private_data : %x\n",(int)(&filp->private_data)); printk("<1>open filp->private_data : %d\n",(int)((struct driver_info *)(filp->private_data))->num); printk("<1>open filp->private_data : %s\n",(char *)((struct driver_info *)(filp->private_data))->msg);
MOD_INC_USE_COUNT; return 0; }
int murray_read(struct inode *inode, struct file *filp, char *buf, int count) { printk("<1>read filp->private_data : %x\n",(int)filp->private_data);
return -1; }
int murray_write(struct inode *inode, struct file *filp, const char *buf, int count) { printk("<1>write filp->private_data : %x\n",(int)(&filp->private_data)); return -1; }
void murray_release (struct inode *inode, struct file *filp) { MOD_DEC_USE_COUNT; printk("<1>murray_release\n"); // if (filp->private_data != NULL) // kfree(filp->private_data); }
---- murray.h #define MURRAY_MINOR 10
// Prototypes
int murray_open(struct inode *inode, struct file *filp); void murray_release (struct inode *inode, struct file *filp); int murray_read(struct inode *inode, struct file *filp, char *buf, int count); int murray_write(struct inode *inode, struct file *filp, const char *buf, int count);
struct file_operations murray_fops = { NULL, /* lseek */ murray_read, murray_write, NULL, /* readdir */ NULL, /* select (poll) */ NULL, /* ioctl */ NULL, /* mmap */ murray_open, NULL, /* flush */ murray_release, /* close */ NULL, /* fsync */ NULL, /* no media change */ NULL, /* revalidate */ NULL /* lock */ };
static struct miscdevice murray_device = { MURRAY_MINOR, "murray", &murray_fops };
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |