Commit 3a453bd4 authored by Chuck Lever's avatar Chuck Lever Committed by Linus Torvalds

[PATCH] add struct file* to ->direct_IO addr space op

This makes file credentials available to the ->direct_IO address space
operation by replacing its struct inode* argument with a struct file*
argument.  this patch is a prerequisite for NFS direct I/O support.  it
breaks the raw device driver.
parent 7570df54
...@@ -222,7 +222,7 @@ rw_raw_dev(int rw, struct file *filp, const struct iovec *iov, unsigned long nr_ ...@@ -222,7 +222,7 @@ rw_raw_dev(int rw, struct file *filp, const struct iovec *iov, unsigned long nr_
count = inode->i_size - *offp; count = inode->i_size - *offp;
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, count); nr_segs = iov_shorten((struct iovec *)iov, nr_segs, count);
} }
ret = generic_file_direct_IO(rw, inode, iov, *offp, nr_segs); ret = generic_file_direct_IO(rw, filp, iov, *offp, nr_segs);
if (ret > 0) if (ret > 0)
*offp += ret; *offp += ret;
......
...@@ -116,9 +116,11 @@ blkdev_get_blocks(struct inode *inode, sector_t iblock, ...@@ -116,9 +116,11 @@ blkdev_get_blocks(struct inode *inode, sector_t iblock,
} }
static int static int
blkdev_direct_IO(int rw, struct inode *inode, const struct iovec *iov, blkdev_direct_IO(int rw, struct file *file, const struct iovec *iov,
loff_t offset, unsigned long nr_segs) loff_t offset, unsigned long nr_segs)
{ {
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
return generic_direct_IO(rw, inode, iov, offset, return generic_direct_IO(rw, inode, iov, offset,
nr_segs, blkdev_get_blocks); nr_segs, blkdev_get_blocks);
} }
......
...@@ -646,14 +646,14 @@ generic_direct_IO(int rw, struct inode *inode, const struct iovec *iov, ...@@ -646,14 +646,14 @@ generic_direct_IO(int rw, struct inode *inode, const struct iovec *iov,
} }
ssize_t ssize_t
generic_file_direct_IO(int rw, struct inode *inode, const struct iovec *iov, generic_file_direct_IO(int rw, struct file *file, const struct iovec *iov,
loff_t offset, unsigned long nr_segs) loff_t offset, unsigned long nr_segs)
{ {
struct address_space *mapping = inode->i_mapping; struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
ssize_t retval; ssize_t retval;
retval = mapping->a_ops->direct_IO(rw, inode, iov, offset, nr_segs); retval = mapping->a_ops->direct_IO(rw, file, iov, offset, nr_segs);
if (inode->i_mapping->nrpages) if (mapping->nrpages)
invalidate_inode_pages2(inode->i_mapping); invalidate_inode_pages2(mapping);
return retval; return retval;
} }
...@@ -619,9 +619,11 @@ ext2_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks, ...@@ -619,9 +619,11 @@ ext2_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks,
} }
static int static int
ext2_direct_IO(int rw, struct inode *inode, const struct iovec *iov, ext2_direct_IO(int rw, struct file *file, const struct iovec *iov,
loff_t offset, unsigned long nr_segs) loff_t offset, unsigned long nr_segs)
{ {
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
return generic_direct_IO(rw, inode, iov, return generic_direct_IO(rw, inode, iov,
offset, nr_segs, ext2_get_blocks); offset, nr_segs, ext2_get_blocks);
} }
......
...@@ -1399,10 +1399,11 @@ static int ext3_releasepage(struct page *page, int wait) ...@@ -1399,10 +1399,11 @@ static int ext3_releasepage(struct page *page, int wait)
* If the O_DIRECT write is intantiating holes inside i_size and the machine * If the O_DIRECT write is intantiating holes inside i_size and the machine
* crashes then stale disk data _may_ be exposed inside the file. * crashes then stale disk data _may_ be exposed inside the file.
*/ */
static int ext3_direct_IO(int rw, struct inode *inode, static int ext3_direct_IO(int rw, struct file *file,
const struct iovec *iov, loff_t offset, const struct iovec *iov, loff_t offset,
unsigned long nr_segs) unsigned long nr_segs)
{ {
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
struct ext3_inode_info *ei = EXT3_I(inode); struct ext3_inode_info *ei = EXT3_I(inode);
handle_t *handle = NULL; handle_t *handle = NULL;
int ret; int ret;
......
...@@ -310,9 +310,11 @@ static int jfs_bmap(struct address_space *mapping, long block) ...@@ -310,9 +310,11 @@ static int jfs_bmap(struct address_space *mapping, long block)
return generic_block_bmap(mapping, block, jfs_get_block); return generic_block_bmap(mapping, block, jfs_get_block);
} }
static int jfs_direct_IO(int rw, struct inode *inode, const struct iovec *iov, static int jfs_direct_IO(int rw, struct file *file, const struct iovec *iov,
loff_t offset, unsigned long nr_segs) loff_t offset, unsigned long nr_segs)
{ {
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
return generic_direct_IO(rw, inode, iov, return generic_direct_IO(rw, inode, iov,
offset, nr_segs, jfs_get_blocks); offset, nr_segs, jfs_get_blocks);
} }
......
...@@ -681,11 +681,13 @@ linvfs_get_blocks_direct( ...@@ -681,11 +681,13 @@ linvfs_get_blocks_direct(
STATIC int STATIC int
linvfs_direct_IO( linvfs_direct_IO(
int rw, int rw,
struct inode *inode, struct file *file,
const struct iovec *iov, const struct iovec *iov,
loff_t offset, loff_t offset,
unsigned long nr_segs) unsigned long nr_segs)
{ {
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
return generic_direct_IO(rw, inode, iov, offset, nr_segs, return generic_direct_IO(rw, inode, iov, offset, nr_segs,
linvfs_get_blocks_direct); linvfs_get_blocks_direct);
} }
......
...@@ -308,7 +308,8 @@ struct address_space_operations { ...@@ -308,7 +308,8 @@ struct address_space_operations {
int (*bmap)(struct address_space *, long); int (*bmap)(struct address_space *, long);
int (*invalidatepage) (struct page *, unsigned long); int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int); int (*releasepage) (struct page *, int);
int (*direct_IO)(int, struct inode *, const struct iovec *iov, loff_t offset, unsigned long nr_segs); int (*direct_IO)(int, struct file *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
}; };
struct backing_dev_info; struct backing_dev_info;
...@@ -1247,7 +1248,7 @@ ssize_t generic_file_write_nolock(struct file *file, const struct iovec *iov, ...@@ -1247,7 +1248,7 @@ ssize_t generic_file_write_nolock(struct file *file, const struct iovec *iov,
unsigned long nr_segs, loff_t *ppos); unsigned long nr_segs, loff_t *ppos);
extern ssize_t generic_file_sendfile(struct file *, struct file *, loff_t *, size_t); extern ssize_t generic_file_sendfile(struct file *, struct file *, loff_t *, size_t);
extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t); extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
extern ssize_t generic_file_direct_IO(int rw, struct inode *inode, extern ssize_t generic_file_direct_IO(int rw, struct file *file,
const struct iovec *iov, loff_t offset, unsigned long nr_segs); const struct iovec *iov, loff_t offset, unsigned long nr_segs);
extern int generic_direct_IO(int rw, struct inode *inode, const struct iovec extern int generic_direct_IO(int rw, struct inode *inode, const struct iovec
*iov, loff_t offset, unsigned long nr_segs, get_blocks_t *get_blocks); *iov, loff_t offset, unsigned long nr_segs, get_blocks_t *get_blocks);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/uio.h>
#include <linux/nfs_fs_sb.h> #include <linux/nfs_fs_sb.h>
...@@ -283,6 +284,12 @@ nfs_file_cred(struct file *file) ...@@ -283,6 +284,12 @@ nfs_file_cred(struct file *file)
return cred; return cred;
} }
/*
* linux/fs/nfs/direct.c
*/
extern int nfs_direct_IO(int, struct file *, const struct iovec *, loff_t,
unsigned long);
/* /*
* linux/fs/nfs/dir.c * linux/fs/nfs/dir.c
*/ */
......
...@@ -192,6 +192,7 @@ EXPORT_SYMBOL(invalidate_bdev); ...@@ -192,6 +192,7 @@ EXPORT_SYMBOL(invalidate_bdev);
EXPORT_SYMBOL(invalidate_inodes); EXPORT_SYMBOL(invalidate_inodes);
EXPORT_SYMBOL(invalidate_device); EXPORT_SYMBOL(invalidate_device);
EXPORT_SYMBOL(invalidate_inode_pages); EXPORT_SYMBOL(invalidate_inode_pages);
EXPORT_SYMBOL_GPL(invalidate_inode_pages2);
EXPORT_SYMBOL(truncate_inode_pages); EXPORT_SYMBOL(truncate_inode_pages);
EXPORT_SYMBOL(fsync_bdev); EXPORT_SYMBOL(fsync_bdev);
EXPORT_SYMBOL(permission); EXPORT_SYMBOL(permission);
......
...@@ -1158,7 +1158,7 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, ...@@ -1158,7 +1158,7 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
nr_segs = iov_shorten((struct iovec *)iov, nr_segs = iov_shorten((struct iovec *)iov,
nr_segs, count); nr_segs, count);
} }
retval = generic_file_direct_IO(READ, inode, retval = generic_file_direct_IO(READ, filp,
iov, pos, nr_segs); iov, pos, nr_segs);
if (retval > 0) if (retval > 0)
*ppos = pos + retval; *ppos = pos + retval;
...@@ -1840,7 +1840,7 @@ generic_file_write_nolock(struct file *file, const struct iovec *iov, ...@@ -1840,7 +1840,7 @@ generic_file_write_nolock(struct file *file, const struct iovec *iov,
if (count != ocount) if (count != ocount)
nr_segs = iov_shorten((struct iovec *)iov, nr_segs = iov_shorten((struct iovec *)iov,
nr_segs, count); nr_segs, count);
written = generic_file_direct_IO(WRITE, inode, written = generic_file_direct_IO(WRITE, file,
iov, pos, nr_segs); iov, pos, nr_segs);
if (written > 0) { if (written > 0) {
loff_t end = pos + written; loff_t end = pos + written;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment