fs: symlink write_begin allocation context fix
[safe/jmp/linux-2.6] / fs / fuse / file.c
index 9ced35b..4c9ee70 100644 (file)
@@ -101,6 +101,8 @@ void fuse_finish_open(struct inode *inode, struct file *file,
                file->f_op = &fuse_direct_io_file_operations;
        if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
                invalidate_inode_pages2(inode->i_mapping);
+       if (outarg->open_flags & FOPEN_NONSEEKABLE)
+               nonseekable_open(inode, file);
        ff->fh = outarg->fh;
        file->private_data = fuse_file_get(ff);
 }
@@ -644,7 +646,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping,
 {
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
 
-       *pagep = __grab_cache_page(mapping, index);
+       *pagep = grab_cache_page_write_begin(mapping, index, flags);
        if (!*pagep)
                return -ENOMEM;
        return 0;
@@ -777,7 +779,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                        break;
 
                err = -ENOMEM;
-               page = __grab_cache_page(mapping, index);
+               page = grab_cache_page_write_begin(mapping, index, 0);
                if (!page)
                        break;
 
@@ -804,6 +806,8 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
                if (offset == PAGE_CACHE_SIZE)
                        offset = 0;
 
+               if (!fc->big_writes)
+                       break;
        } while (iov_iter_count(ii) && count < fc->max_write &&
                 req->num_pages < FUSE_MAX_PAGES_PER_REQ && offset == 0);
 
@@ -891,7 +895,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        if (count == 0)
                goto out;
 
-       err = remove_suid(file->f_path.dentry);
+       err = file_remove_suid(file);
        if (err)
                goto out;
 
@@ -934,7 +938,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
 
        nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
        npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ);
+       npages = clamp(npages, 1, FUSE_MAX_PAGES_PER_REQ);
        down_read(&current->mm->mmap_sem);
        npages = get_user_pages(current, current->mm, user_addr, npages, write,
                                0, req->pages, NULL);
@@ -1339,6 +1343,11 @@ 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;
 
+       if (fl->fl_lmops && fl->fl_lmops->fl_grant) {
+               /* NLM needs asynchronous locks, which we don't support yet */
+               return -ENOLCK;
+       }
+
        /* Unlock on close is handled by the flush method */
        if (fl->fl_flags & FL_CLOSE)
                return 0;
@@ -1363,7 +1372,9 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
        struct fuse_conn *fc = get_fuse_conn(inode);
        int err;
 
-       if (cmd == F_GETLK) {
+       if (cmd == F_CANCELLK) {
+               err = 0;
+       } else if (cmd == F_GETLK) {
                if (fc->no_lock) {
                        posix_test_lock(file, fl);
                        err = 0;
@@ -1371,7 +1382,7 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
                        err = fuse_getlk(file, fl);
        } else {
                if (fc->no_lock)
-                       err = posix_lock_file_wait(file, fl);
+                       err = posix_lock_file(file, fl, NULL);
                else
                        err = fuse_setlk(file, fl, 0);
        }
@@ -1439,6 +1450,9 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
        mutex_lock(&inode->i_mutex);
        switch (origin) {
        case SEEK_END:
+               retval = fuse_update_attributes(inode, NULL, file, NULL);
+               if (retval)
+                       return retval;
                offset += i_size_read(inode);
                break;
        case SEEK_CUR: