Commit 5760495a authored by Andi Kleen's avatar Andi Kleen Committed by root

vfs: add generic_file_llseek_size

Add a generic_file_llseek variant to the VFS that allows passing in
the maximum file size of the file system, instead of always
using maxbytes from the superblock.

This can be used to eliminate some cut'n'paste seek code in ext4.
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent ef3d0fd2
...@@ -51,23 +51,23 @@ static loff_t lseek_execute(struct file *file, struct inode *inode, ...@@ -51,23 +51,23 @@ static loff_t lseek_execute(struct file *file, struct inode *inode,
} }
/** /**
* generic_file_llseek - generic llseek implementation for regular files * generic_file_llseek_size - generic llseek implementation for regular files
* @file: file structure to seek on * @file: file structure to seek on
* @offset: file offset to seek to * @offset: file offset to seek to
* @origin: type of seek * @origin: type of seek
* @size: max size of file system
* *
* This is a generic implemenation of ->llseek usable for all normal local * This is a variant of generic_file_llseek that allows passing in a custom
* filesystems. It just updates the file offset to the value specified by * file size.
* @offset and @origin under i_mutex.
* *
* Synchronization: * Synchronization:
* SEEK_SET is unsynchronized (but atomic on 64bit platforms) * SEEK_SET and SEEK_END are unsynchronized (but atomic on 64bit platforms)
* SEEK_CUR is synchronized against other SEEK_CURs, but not read/writes. * SEEK_CUR is synchronized against other SEEK_CURs, but not read/writes.
* read/writes behave like SEEK_SET against seeks. * read/writes behave like SEEK_SET against seeks.
* SEEK_END
*/ */
loff_t loff_t
generic_file_llseek(struct file *file, loff_t offset, int origin) generic_file_llseek_size(struct file *file, loff_t offset, int origin,
loff_t maxsize)
{ {
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
...@@ -91,7 +91,7 @@ generic_file_llseek(struct file *file, loff_t offset, int origin) ...@@ -91,7 +91,7 @@ generic_file_llseek(struct file *file, loff_t offset, int origin)
*/ */
spin_lock(&file->f_lock); spin_lock(&file->f_lock);
offset = lseek_execute(file, inode, file->f_pos + offset, offset = lseek_execute(file, inode, file->f_pos + offset,
inode->i_sb->s_maxbytes); maxsize);
spin_unlock(&file->f_lock); spin_unlock(&file->f_lock);
return offset; return offset;
case SEEK_DATA: case SEEK_DATA:
...@@ -113,7 +113,26 @@ generic_file_llseek(struct file *file, loff_t offset, int origin) ...@@ -113,7 +113,26 @@ generic_file_llseek(struct file *file, loff_t offset, int origin)
break; break;
} }
return lseek_execute(file, inode, offset, inode->i_sb->s_maxbytes); return lseek_execute(file, inode, offset, maxsize);
}
EXPORT_SYMBOL(generic_file_llseek_size);
/**
* generic_file_llseek - generic llseek implementation for regular files
* @file: file structure to seek on
* @offset: file offset to seek to
* @origin: type of seek
*
* This is a generic implemenation of ->llseek useable for all normal local
* filesystems. It just updates the file offset to the value specified by
* @offset and @origin under i_mutex.
*/
loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
{
struct inode *inode = file->f_mapping->host;
return generic_file_llseek_size(file, offset, origin,
inode->i_sb->s_maxbytes);
} }
EXPORT_SYMBOL(generic_file_llseek); EXPORT_SYMBOL(generic_file_llseek);
......
...@@ -2403,6 +2403,8 @@ file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); ...@@ -2403,6 +2403,8 @@ file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
extern loff_t noop_llseek(struct file *file, loff_t offset, int origin); extern loff_t noop_llseek(struct file *file, loff_t offset, int origin);
extern loff_t no_llseek(struct file *file, loff_t offset, int origin); extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin); extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
int origin, loff_t maxsize);
extern int generic_file_open(struct inode * inode, struct file * filp); extern int generic_file_open(struct inode * inode, struct file * filp);
extern int nonseekable_open(struct inode * inode, struct file * filp); extern int nonseekable_open(struct inode * inode, struct file * filp);
......
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