Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 257392
b: refs/heads/master
c: 982d816
h: refs/heads/master
v: v3
  • Loading branch information
Josef Bacik authored and Al Viro committed Jul 21, 2011
1 parent e1839dd commit 7ed529d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b4d5b10fb2e3a4327838c07d8ebd9e350fcc133d
refs/heads/master: 982d816581eeeacfe5b2b7c6d47d13a157616eff
10 changes: 10 additions & 0 deletions trunk/Documentation/filesystems/porting
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,13 @@ to some pointer to returning that pointer. On errors return ERR_PTR(...).
argument; instead of passing IPERM_FLAG_RCU we add MAY_NOT_BLOCK into mask.
generic_permission() has also lost the check_acl argument; if you want
non-NULL to be used for that inode, put it into ->i_op->check_acl.

--
[mandatory]
If you implement your own ->llseek() you must handle SEEK_HOLE and
SEEK_DATA. You can hanle this by returning -EINVAL, but it would be nicer to
support it in some way. The generic handler assumes that the entire file is
data and there is a virtual hole at the end of the file. So if the provided
offset is less than i_size and SEEK_DATA is specified, return the same offset.
If the above is true for the offset and you are given SEEK_HOLE, return the end
of the file. If the offset is i_size or greater return -ENXIO in either case.
44 changes: 41 additions & 3 deletions trunk/fs/read_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
return file->f_pos;
offset += file->f_pos;
break;
case SEEK_DATA:
/*
* In the generic case the entire file is data, so as long as
* offset isn't at the end of the file then the offset is data.
*/
if (offset >= inode->i_size)
return -ENXIO;
break;
case SEEK_HOLE:
/*
* There is a virtual hole at the end of the file, so as long as
* offset isn't i_size or larger, return i_size.
*/
if (offset >= inode->i_size)
return -ENXIO;
offset = inode->i_size;
break;
}

if (offset < 0 && !unsigned_offsets(file))
Expand Down Expand Up @@ -128,19 +145,40 @@ EXPORT_SYMBOL(no_llseek);

loff_t default_llseek(struct file *file, loff_t offset, int origin)
{
struct inode *inode = file->f_path.dentry->d_inode;
loff_t retval;

mutex_lock(&file->f_dentry->d_inode->i_mutex);
mutex_lock(&inode->i_mutex);
switch (origin) {
case SEEK_END:
offset += i_size_read(file->f_path.dentry->d_inode);
offset += i_size_read(inode);
break;
case SEEK_CUR:
if (offset == 0) {
retval = file->f_pos;
goto out;
}
offset += file->f_pos;
break;
case SEEK_DATA:
/*
* In the generic case the entire file is data, so as
* long as offset isn't at the end of the file then the
* offset is data.
*/
if (offset >= inode->i_size)
return -ENXIO;
break;
case SEEK_HOLE:
/*
* There is a virtual hole at the end of the file, so
* as long as offset isn't i_size or larger, return
* i_size.
*/
if (offset >= inode->i_size)
return -ENXIO;
offset = inode->i_size;
break;
}
retval = -EINVAL;
if (offset >= 0 || unsigned_offsets(file)) {
Expand All @@ -151,7 +189,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
retval = offset;
}
out:
mutex_unlock(&file->f_dentry->d_inode->i_mutex);
mutex_unlock(&inode->i_mutex);
return retval;
}
EXPORT_SYMBOL(default_llseek);
Expand Down
4 changes: 3 additions & 1 deletion trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
#define SEEK_SET 0 /* seek relative to beginning of file */
#define SEEK_CUR 1 /* seek relative to current file position */
#define SEEK_END 2 /* seek relative to end of file */
#define SEEK_MAX SEEK_END
#define SEEK_DATA 3 /* seek to the next data */
#define SEEK_HOLE 4 /* seek to the next hole */
#define SEEK_MAX SEEK_HOLE

struct fstrim_range {
__u64 start;
Expand Down

0 comments on commit 7ed529d

Please sign in to comment.