filp->private_data problems

Murray Stokely (murray@cdrom.com)
Wed, 27 Oct 1999 04:08:41 -0700 (PDT)


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/