EXT3 file operations - filesystems

I am trying to follow how Linux deals with EXT3 files.
I am looking at fs/ext3/file.c where there are file operations that deal with the files are present:
const struct file_operations ext3_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.unlocked_ioctl = ext3_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ext3_compat_ioctl,
#endif
.mmap = generic_file_mmap,
.open = dquot_file_open,
.release = ext3_release_file,
.fsync = ext3_sync_file,
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
};
How can I find when does .open is replaced by the function "dquot_file_open" for example?
Should I follow the system call defined in fs/open.c:
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
Or should I be looking at other functions?
I am working on Linux 3.7.6 for User-Mode-Linux

The Linux kernel is organized in an OOP manner (though written in C). The struct file_operations is really a class, the members (function pointers) are the function members ("methods" for Java heads) of the class. The code you quote serves to set up the ext3 object by filling in the function pointers. This is done at compile/link time.
The open(2) system call calls this indirectly, by finding out the struct file_operations relevant for the file system at hand, and calling its open member.
I'd suggest you take a look at the kernelnewbies page for an overall view and more detailed help.

Related

Standard Library vs Windows API Speed

My question is about whether or not I should use the Windows API if I'm trying to get the most speed out of my program, where I could instead use a Standard Library function.
I assume the answer isn't consistent among every call; Specifically, I'm curious about stat() vs dwFileAttributes, if I wanted to figure out if a file was a directory or not for example (assuming file_name is a string containing the full path to the file):
WIN32_FIND_DATA fileData;
HANDLE hSearch;
hSearch = FindFirstFile(TEXT(file_name), &fileData);
int isDir = fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
vs.
struct stat info;
stat(file_name, &info);
int isDir = S_ISDIR(info.st_mode);
If anyone knows, or can elaborate on what the speed difference between these libraries generally is (if any) I'd appreciate it.
Not an answer regarding speed, but #The Corn Inspector, the MSVC CRT code is open sourced. If you look at an older version ( before .net and common UCRT), and look at the stat() function, it is INDEED a wrapper around the same OS call.
int __cdecl _tstat (
REG1 const _TSCHAR *name,
REG2 struct _stat *buf
)
{ // stuff omitted for clarity
_TSCHAR * path;
_TSCHAR pathbuf[ _MAX_PATH ];
int drive; /* A: = 1, B: = 2, etc. */
HANDLE findhandle;
WIN32_FIND_DATA findbuf;
/* Call Find Match File */
findhandle = FindFirstFile((_TSCHAR *)name, &findbuf);
Of course there is addtional code for mapping structures, etc. Looks like it also does some time conversion:
SYSTEMTIME SystemTime;
FILETIME LocalFTime;
if ( !FileTimeToLocalFileTime( &findbuf.ftLastWriteTime,
&LocalFTime ) ||
!FileTimeToSystemTime( &LocalFTime, &SystemTime ) )
{
so theoretically, it could be slower, but probably so insignificant, as to make no practical difference in the context of a complete, complex program. If you are calling stat() a million times, and worry about milliseconds, who knows. Profile it.

What static struct in linux kernel code use for

Hi I am following the book Linux device driver development to write a driver in Linux. In an example code as below:
struct my_gpios {
int reset_gpio;
int led_gpio;
};
static struct my_gpiosneeded_gpios = {
.reset_gpio = 47;
.led_gpio = 41;
};
static struct resource needed_resources[] = {
[0] = { /* The first memory region */
.start = JZ4740_UDC_BASE_ADDR,
.end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
.flags = IORESOURCE_MEM,
.name = "mem1",
},
[1] = {
.start = JZ4740_UDC_BASE_ADDR2,Platform Device Drivers
[ 126 ]
.end = JZ4740_UDC_BASE_ADDR2 + 0x10000 -1,
.flags = IORESOURCE_MEM,
.name = "mem2",
},
};
static struct platform_devicemy_device = {
.name = "my-platform-device",
.id = 0,
.dev = {
.platform_data = &needed_gpios,
},
.resource = needed_resources,
.num_resources = ARRY_SIZE(needed_resources),
};
platform_device_register(&my_device);
I do not understand the syntax static struct_gpiosneeded_gpios = {} meaning and why have a dot in .reset_gpio. And what is the meaning of the syntax static struct [] = {[0]={}, [1]={}}?
Could you please give me a reference link or keyword or example about static struct {.a = VALUE, .b = VALUE,};?
static struct something x = {
.field_one = 123,
.field_two = 456
};
This is a struct initialization syntax, standard from C99 (see here). This example creates a variable of type struct something named x, with fields field_one and field_two initialized to the specified values, and any other field initialized to 0. The static keyword is a storage duration specifier (see here).
static struct something x[] = {[0]={ ... }, [1]={ ... }};
This is a mix of both struct initialization and array initialization syntax, again standard from C99 (see here). This example creates an array x of variables of type struct something, the one at index 0 is initialized with the contents of the {...} initializer, and the same goes for the one at index 1. Since the greatest specified index is 1, the array size is 2.
I do not understand why they named the type is u32 or what is the purpose of __raw.
The u32 type is just a short alias for uint32_t.
I am not sure exactly where you saw __raw, since I don't seem to find anything like it in the kernel source. In any case, the Linux kernel as a series of compile-time annotations used for variables that have different purposes (__user, __rcu, etc). Those are not part of the C standard and frequently not even GCC extensions. They are mostly hints to be used by Sparse, the Linux kernel semantic checker.
Is there any standard or rule for naming the variable, macro, type,... in kernel?
Refer to the Linux kernel coding style documentation page for more information. I would suggest you to read it all before trying to do any kind of kernel programming. The more documentation pages you read, the better.
And what C standard i have to compliance when writing code in linux driver?
Use anything that is C99 or older and you will be fine. The Linux kernel code does not adhere to a single C standard, and various parts of the code aren't even standard compliant, but use GCC extensions. See here for more information.
You don't usually choose the standard when compiling, the kernel Makefile does this for you, and it should default to C90.
In any case, those are a lot of questions. If you have a specific question I would suggest you to ask it separately so that people are able to give you a focused and more extensive answer, since it's off topic to ask too broad or too many questions.

purpose of __devexit_p in driver files

Can anyone please tell me the purpose of __devexit_p part in driver files ?
I find __devexit_p is normally using with remove functions in the driver code
Example 1:
static struct i2c_driver lsm9ds0_driver = {
.driver = {
.owner = THIS_MODULE,
.name = LSM9DS0_DEV_NAME,
},
.probe = lsm9ds0_probe,
.remove = __devexit_p(lsm9ds0_remove),
.id_table = lsm9ds0_id,
};
Example 2:
static struct spi_driver light_driver = {
.driver = {
.name = "light",
.owner = THIS_MODULE,
},
.probe = light_probe,
.remove = __devexit_p(light_remove),
};
Is there any difference if I removed __devexit_p from above examples?
Will it affect the performance of the driver when __devexit_p removed?
Based on this LXR listing from 2.6.32:
/*
Functions marked as __devexit may be discarded at kernel link time,
depending on config options. Newer versions of binutils detect references
from retained sections to discarded sections and flag an error. Pointers to
__devexit functions must use __devexit_p(function_name), the wrapper will
insert either the function_name or NULL, depending on the config options.
*/
#if defined(MODULE) || defined(CONFIG_HOTPLUG)
#define __devexit_p(x) x
#else
#define __devexit_p(x) NULL
#endif
it seems to be used to conditionally expand it to the given parameter or NULL based on the code being compiled as part of a kernel module (MODULE) and on the CONFIG_HOTPLUG kernel option.

Designated Initializers followed by function name

How does this work, given a function header,
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
In the struct a designated identifier is used, in this case read followed by the function name, I do understand this is the same as .read = memory_read. However I am unsure of its purpose. Does this provide a method call the memory_read function elsewhere in the code?
struct file_operations memory_fops = {
read: memory_read,
write: memory_write,
open: memory_open,
release: memory_release
};
Yes, this structure contains a set of function pointers that will be used elsewhere in the program. Look for something like:
memory_fops.read(......)
And so on.
The version "name : value" should not be used anymore. This is an gcc extension which has become obsolete with C99 which uses the form ".name = value". If that is a a snippet from a Linux driver, you might stick to it, however, if the style guide demands it. Otherwise I would change it to the standard-compliant version.

kernel module write to proc

I have made the following kernel module to create a process "hello_proc" in /proc directory:
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
static int hello_proc_show(struct seq_file *m, void *v) {
seq_printf(m, "P5 : Hello proc!\n");
return 0;
}
static int hello_proc_open(struct inode *inode, struct file *file) {
return single_open(file, hello_proc_show, NULL);
}
static const struct file_operations hello_proc_fops = {
.owner = THIS_MODULE,
.open = hello_proc_open,
.read = seq_read,
.write = seq_write,
.llseek = seq_lseek,
.release = single_release,
};
static int hello_proc_init(void) {
proc_create("hello_proc", 0, NULL, &hello_proc_fops);
printk("P5 : Process hello proc created");
return 0;
}
static void hello_proc_exit(void) {
remove_proc_entry("hello_proc", NULL);
}
MODULE_LICENSE("GPL");
module_init(hello_proc_init);
module_exit(hello_proc_exit);
I inserted the module and a proc file "hello_proc" was created successfully in directory /proc. The next thing I want to do is to write the output of command:
ls -l -t /proc | head -21 > /proc/hello_proc
to file "hello_proc" followed by reading as well. When I do (as root):
root#anubhav-Inspiron-3421:~$ ls -l -t /proc | head -21 > /proc/hello_proc
the execution just stops.
Now, I checked a lot of codes and resources on internet, but could not find one that explains how to write to a proc file. No resource on youtube either.
The best thing I found for writing to proc file were codes that were creating proc files using function "create_proc_entry", which looked fairly simple but for an older kernel version, different than mine. Any suggestions/directions to move ahead.
seq_write doesn't do what you might think. It's actually like seq_printf except it just writes a fixed number of bytes (rather than formatted outpuut). The seq_xxx API doesn't support writing to the device. You have to implement that separately.
For a fairly simple model of how to create a writable device using single_open on the read side, take a look at proc_pid_set_comm_operations, which implements /proc/<pid>/comm and also supports writing.
Also, note that create_proc_entry was deprecated but it's pretty straight-forward to change create_proc_entry to proc_create. As described in Documentation/filesystems/seq_file.txt:
- entry = create_proc_entry("sequence", 0, NULL);
- if (entry)
- entry->proc_fops = &ct_file_ops;
+ entry = proc_create("sequence", 0, NULL, &ct_file_ops);

Resources