Good day. Im trying to get fullpath from struct file
char *buf = (char*)__get_free_page(GFP_USER);
char *buf2 = (char*)__get_free_page(GFP_USER);
char *name = dentry_path(file->f_dentry, buf, PAGE_SIZE);
char *root = dentry_path(file->f_vfsmnt->mnt_mountpoint, buf2, PAGE_SIZE);
***some operations***
free_page((unsigned long)buf);
free_page((unsigned long)buf2);
kfree(*root);
kfree(*name);
But i get an error
fs/read_write.c:707: error: request for member 'mnt_mountpoint' in something not a structure or union
How can i get vsfmount struct from file?
Kernel version linux-2.6.37.6
In kernel 2.6, your code should work.
In kernel 3.0, struct vfsmount contains member mnt_root, of type struct dentry.
I think this would give you the mount point path.
Which are you using?
Judging by the error, is it possible that f_vfsmnt is allocated in the file-struct?
I that case the mnt_mountpoint field should be accessible via file->f_vfsmnt.mnt_mountpoint.
Related
I wrote a platform driver for a peripheral we developed and would like to expose some configuration options to the sysfs. I have managed to create the appropriate files using attribute structs (see below) and sysfs_create_file in the probe function, but I can't figure out how to attach the show/store functions to the structs in a platform driver.
Most resources I found online used a device_attribute struct or something similar to create their files, is that also appropriate here? Is there another way to do this for a platform driver?
My attribute struct looks like this:
struct attribute subkey_attr = {
.name = "subkeys",
.mode = S_IWUGO | S_IRUGO,
};
And I register the file using this call:
riddler_kobject = &pdev->dev.kobj;
ret_val = sysfs_create_file(riddler_kobject, &subkey_attr);
It boils down to next:
reuse existing kobject from struct device (from your struct platform_device) for sysfs_create_group() (instead of creating your own kobject)
use DEVICE_ATTR() to declare struct device_attribute instead of regular __ATTR(), which creates struct kobj_attribute.
Here is how I created sysfs attributes for my platform driver.
Create structure you'll be using as private data in show() / store() operations for your sysfs attribute (file). For example:
struct mydrv {
struct device *dev;
long myparam;
};
Allocate this structure in your driver's probe():
static int mydrv_probe(struct platform_device *pdev)
{
struct mydrv *mydrv;
mydrv = devm_kzalloc(&pdev->dev, sizeof(*mydrv), GFP_KERNEL);
mydrv->dev = &pdev->dev;
platform_set_drvdata(pdev, mydrv);
...
}
Create show() / store() functions:
static ssize_t mydrv_myparam_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mydrv *mydrv = dev_get_drvdata(dev);
int len;
len = sprintf(buf, "%d\n", mydrv->myparam);
if (len <= 0)
dev_err(dev, "mydrv: Invalid sprintf len: %d\n", len);
return len;
}
static ssize_t mydrv_myparam_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct mydrv *mydrv = dev_get_drvdata(dev);
kstrtol(buf, 10, &mydrv->myparam);
return count;
}
Create device attribute for those functions (right after those functions):
static DEVICE_ATTR(myparam, S_IRUGO | S_IWUSR, mydrv_myparam_show,
mydrv_myparam_store);
Declare attributes table (listing in fact sysfs files for you driver):
static struct attribute *mydrv_attrs[] = {
&dev_attr_myparam.attr,
NULL
};
Declare attribute group (specifying in fact sysfs directory for your driver):
static struct attribute_group mydrv_group = {
.name = "mydrv",
.attrs = mydrv_attrs,
};
static struct attribute_group *mydrv_groups[] = {
&mydrv_group,
NULL
}
which can be actually replaced with one line:
ATTRIBUTE_GROUPS(mydrv);
Create sysfs directory and files in your driver's probe() function:
static int mydrv_probe(struct platform_device *pdev)
{
int ret;
...
ret = sysfs_create_group(&pdev->dev.kobj, &mydrv_group);
if (ret) {
dev_err(&pdev->dev, "sysfs creation failed\n");
return ret;
}
...
}
Remove your sysfs files in your driver's remove() function:
static int mydrv_remove(struct platform_device *pdev)
{
sysfs_remove_group(&pdev->dev.kobj, &mydrv_group);
...
}
Race condition note
As #FranzForstmayr correctly pointed out, there may be race condition when adding sysfs files with sysfs_create_group() in mydrv_probe(). That's because user-space can be already notified that those files exist before mydrv_probe() called (where those files are actually being created by sysfs_create_group() function). This issue covered in details in "How to Create a sysfs File Correctly" article by Greg Kroah-Hartman.
So in our case of platform_device, instead of calling sysfs_create_group() (and its counterpart sysfs_remove_group()), you can use default attribute group. To do so, you need to assign corresponding .groups field of your struct device to your attribute groups variable:
static int mydrv_probe(struct platform_device *pdev)
{
...
pdev->dev.groups = mydrv_groups;
...
}
DISCLAIMER: I didn't test this code, though it should work, because of this code.
See [1,2,3] links for more insights on mentioned race condition.
For more examples, run next command in kernel source directory:
$ git grep -l --all-match -e platform_device -e attribute -e '\.groups =' -- drivers/
Also you can search by "default attribute" in commit messages:
$ git log --no-merges --oneline --grep="default attribute" -- drivers/
Some commits I found this way: [4,5,6,7].
References
[1] My attributes are way too racy, what should I do?
[2] PATCH: sysfs: add devm_sysfs_create_group() and friends
[3] [GIT PATCH] Driver core patches for 3.11-rc2
[4] commit 1
[5] commit 2
[6] commit 3
[7] commit 4
Not enough reputation to post a comment, but I just want to comment on the default attribute group note from the accepted answer.
My understanding is that this should not be added in the probe function, as given in the example, but instead should be set in the device struct, (or device_driver, class, or bus depending on your driver) usually defined at the end of your file.
For example:
static struct device iio_evgen_dev = {
.bus = &iio_bus_type,
.groups = iio_evgen_groups,
.release = &iio_evgen_release,
};
from this example
Strangely, according to this it doesn't work correctly when using DEVICE_INT_ATTR to create the attribute, so not sure what that's all about.
Also, I'm not 100% sure, but I think that this is invoked when the driver is loaded, not when the device is probed.
This is an addition to Sam Protsenko's and Anthony's answers
If you create device attributes via the DEVICE_ATTR macros then you have to register the attribute groups (mydrv_groups) in the .dev_groups instead of the .groups field.
static struct device iio_evgen_dev = {
.bus = &iio_bus_type,
.dev_groups = iio_evgen_groups, // .dev_groups for DEVICE_ATTR
.groups = another_attr_group, // .groups for DRIVER_ATTR
.release = &iio_evgen_release,
};
Then the attributes are automatically registered correctly without setting up anything in the probe/remove functions, as described in Greg Kroah-Hartman's article.
Assume that the module has been loaded into the kernel and the driver is registered in
/sys/bus/platform/drivers/mydrv
every device instances will be a subdirectory of the driver's folder like
/sys/bus/platform/drivers/mydrv/mydrv1
/sys/bus/platform/drivers/mydrv/mydrv2
Registering attributes in the .groups field creates the attributes in the driver folder.
Registering attributes in the .dev_groups field creates the attributes in the device's instance folder.
mydrv
├── driver_attr1
├── driver_attr2
└── mydrv1
├── device_attr1
└── device_attr2
The show/store functions of the attributes in the .groups field do not have access to the driver data set via platform_set_drvdata(pdev, mydrv).
At least not by accessing it via dev_get_drvdata(dev).
Accessing the driver data via dev_get_drvdata(dev) returns NULL and dereferencing it will result in a kernel oops.
In turn, he show/store functions of the attributes in the .dev_groups field have access to the driver data via
struct mydrv *mydrv = dev_get_drvdata(dev);
I have been studying I2C driver (client) code for a while.
I have seen this function "i2c_get_clientdata" and "i2c_set_clientdata" every where.
I have seen the this question here .
Use of pointer to structure instead of creating static local copy
Some times i think like it is like "container_of" macro to get a pointer to the structure.
But still i didn't understood properly why to use it and when to use it.
Below i am posting a sample code where I see its usage.
If any one could help me understand why it is used there and when we shall use it when we write our own drivers.
struct max6875_data {
struct i2c_client *fake_client;
struct mutex update_lock;
u32 valid;
u8 data[USER_EEPROM_SIZE];
unsigned long last_updated[USER_EEPROM_SLICES];
};
static ssize_t max6875_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct i2c_client *client = kobj_to_i2c_client(kobj);
struct max6875_data *data = i2c_get_clientdata(client);
int slice, max_slice;
if (off > USER_EEPROM_SIZE)
return 0;
if (off + count > USER_EEPROM_SIZE)
count = USER_EEPROM_SIZE - off;
/* refresh slices which contain requested bytes */
max_slice = (off + count - 1) >> SLICE_BITS;
for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++)
max6875_update_slice(client, slice);
memcpy(buf, &data->data[off], count);
return count;
}
Those functions are used to get/set the void *driver_data pointer that is part of the struct device, itself part of struct i2c_client.
This is a void pointer that is for the driver to use. One would use this pointer mainly to pass driver related data around.
That is what is happening in your example. The max6875_read is a callback getting a structu kobject. That kobject is an i2c_client which is enough to communicate with the underlying device using the driver_data pointer here allows to get back the driver related data (instead of using global variables for example).
Why I get a '__packed__' attribute ignored [-Wattributes] warning in an android NDK Project?
Here is the code
mem_ = malloc(size_);
uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
*ui8_ptr++ = packet_version;
//uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(ui8_ptr);
__packed uint32_t* ui32_ptr = (__packed uint32_t*)(ui8_ptr);
*ui32_ptr++ = size_;
*ui32_ptr++ = flags;
I am using the packed attribute because I think I have alignment problem when casting from uint8_t to uint32_t (See [1]).
[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html
GCC doesn't seem to support the packed attribute for all variables. It is only supported for struct, union, and enum types. So you could try something like this instead:
mem_ = malloc(size_);
uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
*ui8_ptr++ = packet_version;
struct unaligned32_t
{
uint32_t data __attribute__((packed, aligned(1)));
};
//unaligned32_t* ui32_ptr = reinterpret_cast<unaligned32_t*>(ui8_ptr);
unaligned32_t* ui32_ptr = (unaligned32_t*)(ui8_ptr);
(ui32_ptr++)->data = size_;
(ui32_ptr++)->data = flags;
This won't produce the warning unless you use it on a char type, which is already byte aligned anyway.
I'm still investigating if this produces the code I'm aiming for on my ARM micro-controller but it is the only legal way I can think of using the packed attribute.
Here be dragons! Don't take the address of unaligned32_t.data. You should only access the data member of the struct using the . or -> directly, and not via a pointer. See this answer for why.
Link you referenced is for RVDS compiler (probably armcc) and GCC doesn't support packed attribute on pointers for such usage.
I'm trying to view the filename via kgdb, so I cannot call functions and macros to get it programatically. I need to find it by manually inspecting data structures.
Like if I had a breakpoint here in gdb, how could I look around with gdb and find the filename?
I've tried looking around in filp.f_path, filp.f_inode, etc. I cannot see the filename anywhere.
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
struct kiocb kiocb;
ssize_t ret;
init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_left = len;
kiocb.ki_nbytes = len;
ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
return ret;
}
You can get the filename from struct file *filp with filp->f_path.dentry->d_iname.
To get the full path call dentry_path_raw(filp->f_path.dentry,buf,buflen).
In the Linux kernel, the file structure is essentially how the kernel "sees" the file. The kernel is not interested in the file name, just the inode of the open file. This means that all of the other information which is important to the user is lost.
EDIT: This answer is wrong. You can get the dentry using filp->f_path.dentry. From there you can get the name of the dentry or the full path using the relevant FS flags.
The path is stored in the file->f_path structure as it's name implies. Just not in a plain-text form, but parsed into objects that are more useful for kernel operation, namely a chain of dentry structures, and the vfsmount structure pointing to the root of the current subtree.
You can use the d_path function to regenerate a human-readable path name for a struct path like file->f_path. Note that however this is not a cheap operation and it may slow down your workload significantly.
The above mentioned issues about open but unlinked files, multiple hardlinks and similar are valid for mapping from and inode to a pathname, and open file always has a path associated with it. If the file has been unlinked d_path will prepend a " (deleted)" to the name, and if the filename it has been opened with has been changed to something else using rename since it was opened d_path will not print the original name, but the current name of the entry that was used for opening it.
filp->f_path.dentry->d_name.name
This worked for me
I am newbei to driver programming i am started writing the simple char driver . Then i created special file for my char driver mknod /dev/simple-driver c 250 0 .when it type cat /dev/simple-driver. it shows the string "Hello world from Kernel mode!". i know that function
static const char g_s_Hello_World_string[] = "Hello world tamil_vanan!\n\0";
static const ssize_t g_s_Hello_World_size = sizeof(g_s_Hello_World_string);
static ssize_t device_file_read(
struct file *file_ptr
, char __user *user_buffer
, size_t count
, loff_t *possition)
{
printk( KERN_NOTICE "Simple-driver: Device file is read at offset =
%i, read bytes count = %u", (int)*possition , (unsigned int)count );
if( *possition >= g_s_Hello_World_size )
return 0;
if( *possition + count > g_s_Hello_World_size )
count = g_s_Hello_World_size - *possition;
if( copy_to_user(user_buffer, g_s_Hello_World_string + *possition, count) != 0 )
return -EFAULT;
*possition += count;
return count;
}
is get called . This is mapped to (*read) in file_opreation structure of my driver .My question is how this function is get called , how the parameters like struct file,char,count, offset are passed bcoz is i simply typed cat command ..Please elabroate how this happening
In Linux all are considered as files. The type of file, whether it is a driver file or normal file depends upon the mount point where it is mounted.
For Eg: If we consider your case : cat /dev/simple-driver traverses back to the mount point of device files.
From the device file name simple-driver it retrieves Major and Minor number.
From those number(especially from minor number) it associates the driver file for your character driver.
From the driver it uses struct file ops structure to find the read function, which is nothing but your read function:
static ssize_t device_file_read(struct file *file_ptr, char __user *user_buffer, size_t count, loff_t *possition)
User_buffer will always take sizeof(size_t count).It is better to keep a check of buffer(In some cases it throws warning)
String is copied to User_buffer(copy_to_user is used to check kernel flags during copy operation).
postion is 0 for first copy and it increments in the order of count:position+=count.
Once read function returns the buffer to cat. and cat flushes the buffer contents on std_out which is nothing but your console.
cat will use some posix version of read call from glibc. Glibc will put the arguments on the stack or in registers (this depends on your hardware architecture) and will switch to kernel mode. In the kernel the values will be copied to the kernel stack. And in the end your read function will be called.