Re: Problem using O_DIRECT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jun 15, 2005 at 03:38:45PM +0530, linuxprodigy linuxprodigy wrote:
> 	I have successfully written to a file through a kernel module. Now
> what I want is to avoid buffer cache while read/write to a file
> through a kernel module. For that I set O_DIRECT flag like shown in
> the code below. But it the write returns error that invalid argument.
> Anybody knows what might the problem n how do I get around with it? (I
> am using kernel 2.6.9).

Please read the mailing list archives on why reading and writing files
from a kernel module is a bad idea.

As for why it doesn't work: direct IO needs page aligned buffers, and
reads and writes need to be done in multiples of the soft block size of
the device.

> Regards,
> Linux Prodigy.
> 
> //File od1.c
> #include <linux/kernel.h>
> #include <linux/module.h>
> #include <linux/init.h>
> #include <linux/config.h>
> #include <asm/uaccess.h>
> #include <linux/file.h>
> #include <linux/mm.h>
> #include <linux/slab.h>
> 
> static int __init modinit(void)
> {
> 	struct file *f;
> 	mm_segment_t orig_fs;
> 	int lenwrite = 0,i;
> 	char buff[512],fwrite[] = "/root/programs/odirect/try.txt";
             ^^^^^^^^^
You only have a *very* limited stack in the kernel, randomly pushing
512 bytes on it is a very bad idea.

> 	printk(KERN_ALERT "\nHello World 1\n ");
> 	for(i=0; i<512 ; i++)
> 		buff[i] = 'x';

Use memset().

> 	f = filp_open(fwrite,O_WRONLY, 0600);
> 	f->f_flags |= O_DIRECT;
> 
> 
> 	orig_fs = get_fs();
> 	set_fs(KERNEL_DS);
> 	
> 	lenwrite = f->f_op->write(f,buff,512,&f->f_pos);
> 
> 	set_fs(orig_fs);
> 	
> 	printk(KERN_ALERT "\nHello World 1 after writing %d \n",lenwrite);
                           ^^
Remove the \n, the point is that klogd recognises the level of the
message because there is a special sequence on the first three lines
of the line. Putting an \n in the message defeats that purpose and
will give your message the standard priority (KERN_INFO, IIRC).

> 	fput(f);
> 
> 	return 0;
> }
> 
> static void __exit modexit(void)
> {
> 	printk(KERN_ALERT "\nBye World 1 :\n");
> }
> 
> module_init(modinit);
> module_exit(modexit);
> 
> --
> Kernelnewbies: Help each other learn about the Linux kernel.
> Archive:       http://mail.nl.linux.org/kernelnewbies/
> FAQ:           http://kernelnewbies.org/faq/
> 

-- 
Erik Mouw
J.A.K.Mouw@xxxxxxxxxxxxxx  mouw@xxxxxxxxxxxx

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux