git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'for-3.1' of git://linux-nfs.org/~bfields/linux
[pandora-kernel.git]
/
fs
/
fuse
/
file.c
diff --git
a/fs/fuse/file.c
b/fs/fuse/file.c
index
82a6646
..
d480d9a
100644
(file)
--- a/
fs/fuse/file.c
+++ b/
fs/fuse/file.c
@@
-400,7
+400,8
@@
static void fuse_sync_writes(struct inode *inode)
fuse_release_nowrite(inode);
}
fuse_release_nowrite(inode);
}
-int fuse_fsync_common(struct file *file, int datasync, int isdir)
+int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
+ int datasync, int isdir)
{
struct inode *inode = file->f_mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
{
struct inode *inode = file->f_mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
@@
-412,9
+413,15
@@
int fuse_fsync_common(struct file *file, int datasync, int isdir)
if (is_bad_inode(inode))
return -EIO;
if (is_bad_inode(inode))
return -EIO;
+ err = filemap_write_and_wait_range(inode->i_mapping, start, end);
+ if (err)
+ return err;
+
if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
return 0;
if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
return 0;
+ mutex_lock(&inode->i_mutex);
+
/*
* Start writeback against all dirty pages of the inode, then
* wait for all outstanding writes, before sending the FSYNC
/*
* Start writeback against all dirty pages of the inode, then
* wait for all outstanding writes, before sending the FSYNC
@@
-422,13
+429,15
@@
int fuse_fsync_common(struct file *file, int datasync, int isdir)
*/
err = write_inode_now(inode, 0);
if (err)
*/
err = write_inode_now(inode, 0);
if (err)
-
return err
;
+
goto out
;
fuse_sync_writes(inode);
req = fuse_get_req(fc);
fuse_sync_writes(inode);
req = fuse_get_req(fc);
- if (IS_ERR(req))
- return PTR_ERR(req);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto out;
+ }
memset(&inarg, 0, sizeof(inarg));
inarg.fh = ff->fh;
memset(&inarg, 0, sizeof(inarg));
inarg.fh = ff->fh;
@@
-448,12
+457,15
@@
int fuse_fsync_common(struct file *file, int datasync, int isdir)
fc->no_fsync = 1;
err = 0;
}
fc->no_fsync = 1;
err = 0;
}
+out:
+ mutex_unlock(&inode->i_mutex);
return err;
}
return err;
}
-static int fuse_fsync(struct file *file, int datasync)
+static int fuse_fsync(struct file *file, loff_t start, loff_t end,
+ int datasync)
{
{
- return fuse_fsync_common(file, datasync, 0);
+ return fuse_fsync_common(file,
start, end,
datasync, 0);
}
void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,
}
void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,
@@
-1495,7
+1507,7
@@
static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0;
int err;
pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0;
int err;
- if (fl->fl_lmops && fl->fl_lmops->
fl
_grant) {
+ if (fl->fl_lmops && fl->fl_lmops->
lm
_grant) {
/* NLM needs asynchronous locks, which we don't support yet */
return -ENOLCK;
}
/* NLM needs asynchronous locks, which we don't support yet */
return -ENOLCK;
}
@@
-1600,15
+1612,32
@@
static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
struct inode *inode = file->f_path.dentry->d_inode;
mutex_lock(&inode->i_mutex);
struct inode *inode = file->f_path.dentry->d_inode;
mutex_lock(&inode->i_mutex);
- switch (origin) {
- case SEEK_END:
+ if (origin != SEEK_CUR || origin != SEEK_SET) {
retval = fuse_update_attributes(inode, NULL, file, NULL);
if (retval)
goto exit;
retval = fuse_update_attributes(inode, NULL, file, NULL);
if (retval)
goto exit;
+ }
+
+ switch (origin) {
+ case SEEK_END:
offset += i_size_read(inode);
break;
case SEEK_CUR:
offset += file->f_pos;
offset += i_size_read(inode);
break;
case SEEK_CUR:
offset += file->f_pos;
+ break;
+ case SEEK_DATA:
+ if (offset >= i_size_read(inode)) {
+ retval = -ENXIO;
+ goto exit;
+ }
+ break;
+ case SEEK_HOLE:
+ if (offset >= i_size_read(inode)) {
+ retval = -ENXIO;
+ goto exit;
+ }
+ offset = i_size_read(inode);
+ break;
}
retval = -EINVAL;
if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
}
retval = -EINVAL;
if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {