mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse updates from Miklos Szeredi: "This adds SEEK_HOLE and SEEK_DATA support in lseek" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: add support for SEEK_HOLE and SEEK_DATA in lseek
This commit is contained in:
commit
5c89e9ea7e
3 changed files with 84 additions and 9 deletions
|
|
@ -2231,20 +2231,77 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
|
|||
return err ? 0 : outarg.block;
|
||||
}
|
||||
|
||||
static loff_t fuse_lseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
struct fuse_file *ff = file->private_data;
|
||||
FUSE_ARGS(args);
|
||||
struct fuse_lseek_in inarg = {
|
||||
.fh = ff->fh,
|
||||
.offset = offset,
|
||||
.whence = whence
|
||||
};
|
||||
struct fuse_lseek_out outarg;
|
||||
int err;
|
||||
|
||||
if (fc->no_lseek)
|
||||
goto fallback;
|
||||
|
||||
args.in.h.opcode = FUSE_LSEEK;
|
||||
args.in.h.nodeid = ff->nodeid;
|
||||
args.in.numargs = 1;
|
||||
args.in.args[0].size = sizeof(inarg);
|
||||
args.in.args[0].value = &inarg;
|
||||
args.out.numargs = 1;
|
||||
args.out.args[0].size = sizeof(outarg);
|
||||
args.out.args[0].value = &outarg;
|
||||
err = fuse_simple_request(fc, &args);
|
||||
if (err) {
|
||||
if (err == -ENOSYS) {
|
||||
fc->no_lseek = 1;
|
||||
goto fallback;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
return vfs_setpos(file, outarg.offset, inode->i_sb->s_maxbytes);
|
||||
|
||||
fallback:
|
||||
err = fuse_update_attributes(inode, NULL, file, NULL);
|
||||
if (!err)
|
||||
return generic_file_llseek(file, offset, whence);
|
||||
else
|
||||
return err;
|
||||
}
|
||||
|
||||
static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
loff_t retval;
|
||||
struct inode *inode = file_inode(file);
|
||||
|
||||
/* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */
|
||||
if (whence == SEEK_CUR || whence == SEEK_SET)
|
||||
return generic_file_llseek(file, offset, whence);
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
retval = fuse_update_attributes(inode, NULL, file, NULL);
|
||||
if (!retval)
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
case SEEK_CUR:
|
||||
/* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */
|
||||
retval = generic_file_llseek(file, offset, whence);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
break;
|
||||
case SEEK_END:
|
||||
mutex_lock(&inode->i_mutex);
|
||||
retval = fuse_update_attributes(inode, NULL, file, NULL);
|
||||
if (!retval)
|
||||
retval = generic_file_llseek(file, offset, whence);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
break;
|
||||
case SEEK_HOLE:
|
||||
case SEEK_DATA:
|
||||
mutex_lock(&inode->i_mutex);
|
||||
retval = fuse_lseek(file, offset, whence);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
break;
|
||||
default:
|
||||
retval = -EINVAL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -605,6 +605,9 @@ struct fuse_conn {
|
|||
/** Does the filesystem support asynchronous direct-IO submission? */
|
||||
unsigned async_dio:1;
|
||||
|
||||
/** Is lseek not implemented by fs? */
|
||||
unsigned no_lseek:1;
|
||||
|
||||
/** The number of requests waiting for completion */
|
||||
atomic_t num_waiting;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue