fuse: add missing FR_FORCE
[pandora-kernel.git] / fs / fuse / file.c
index 594f07a..1f78f91 100644 (file)
@@ -126,6 +126,7 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
                struct fuse_req *req = ff->reserved_req;
 
                if (sync) {
+                       req->force = 1;
                        fuse_request_send(ff->fc, req);
                        path_put(&req->misc.release.path);
                        fuse_put_request(ff->fc, req);
@@ -519,7 +520,8 @@ static void fuse_read_update_size(struct inode *inode, loff_t size,
        struct fuse_inode *fi = get_fuse_inode(inode);
 
        spin_lock(&fc->lock);
-       if (attr_ver == fi->attr_version && size < inode->i_size) {
+       if (attr_ver == fi->attr_version && size < inode->i_size &&
+           !test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
                fi->attr_version = ++fc->attr_version;
                i_size_write(inode, size);
        }
@@ -849,6 +851,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
 
                mark_page_accessed(page);
 
+               iov_iter_advance(ii, tmp);
                if (!tmp) {
                        unlock_page(page);
                        page_cache_release(page);
@@ -860,7 +863,6 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                req->pages[req->num_pages] = page;
                req->num_pages++;
 
-               iov_iter_advance(ii, tmp);
                count += tmp;
                pos += tmp;
                offset += tmp;
@@ -881,12 +883,16 @@ static ssize_t fuse_perform_write(struct file *file,
 {
        struct inode *inode = mapping->host;
        struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_inode *fi = get_fuse_inode(inode);
        int err = 0;
        ssize_t res = 0;
 
        if (is_bad_inode(inode))
                return -EIO;
 
+       if (inode->i_size < pos + iov_iter_count(ii))
+               set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+
        do {
                struct fuse_req *req;
                ssize_t count;
@@ -921,6 +927,7 @@ static ssize_t fuse_perform_write(struct file *file,
        if (res > 0)
                fuse_write_update_size(inode, pos);
 
+       clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
        fuse_invalidate_attr(inode);
 
        return res > 0 ? res : err;
@@ -1251,7 +1258,6 @@ static int fuse_writepage_locked(struct page *page)
 
        inc_bdi_stat(mapping->backing_dev_info, BDI_WRITEBACK);
        inc_zone_page_state(tmp_page, NR_WRITEBACK_TEMP);
-       end_page_writeback(page);
 
        spin_lock(&fc->lock);
        list_add(&req->writepages_entry, &fi->writepages);
@@ -1259,6 +1265,8 @@ static int fuse_writepage_locked(struct page *page)
        fuse_flush_writepages(inode);
        spin_unlock(&fc->lock);
 
+       end_page_writeback(page);
+
        return 0;
 
 err_free:
@@ -1556,7 +1564,7 @@ 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);
-       if (origin != SEEK_CUR || origin != SEEK_SET) {
+       if (origin != SEEK_CUR && origin != SEEK_SET) {
                retval = fuse_update_attributes(inode, NULL, file, NULL);
                if (retval)
                        goto exit;
@@ -1567,6 +1575,10 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
                offset += i_size_read(inode);
                break;
        case SEEK_CUR:
+               if (offset == 0) {
+                       retval = file->f_pos;
+                       goto exit;
+               }
                offset += file->f_pos;
                break;
        case SEEK_DATA:
@@ -1683,7 +1695,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
        size_t n;
        u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
 
-       for (n = 0; n < count; n++) {
+       for (n = 0; n < count; n++, iov++) {
                if (iov->iov_len > (size_t) max)
                        return -ENOMEM;
                max -= iov->iov_len;