aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r--fs/fuse/file.c134
1 files changed, 88 insertions, 46 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 2ca86141d13a..a7ef5e716f3c 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -113,6 +113,14 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
113 return err; 113 return err;
114} 114}
115 115
116/* Special case for failed iget in CREATE */
117static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req)
118{
119 u64 nodeid = req->in.h.nodeid;
120 fuse_reset_request(req);
121 fuse_send_forget(fc, req, nodeid, 1);
122}
123
116void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff, 124void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
117 u64 nodeid, struct inode *inode, int flags, int isdir) 125 u64 nodeid, struct inode *inode, int flags, int isdir)
118{ 126{
@@ -128,6 +136,8 @@ void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
128 req->in.args[0].size = sizeof(struct fuse_release_in); 136 req->in.args[0].size = sizeof(struct fuse_release_in);
129 req->in.args[0].value = inarg; 137 req->in.args[0].value = inarg;
130 request_send_background(fc, req); 138 request_send_background(fc, req);
139 if (!inode)
140 req->end = fuse_release_end;
131 kfree(ff); 141 kfree(ff);
132} 142}
133 143
@@ -163,6 +173,9 @@ static int fuse_flush(struct file *file)
163 struct fuse_flush_in inarg; 173 struct fuse_flush_in inarg;
164 int err; 174 int err;
165 175
176 if (is_bad_inode(inode))
177 return -EIO;
178
166 if (fc->no_flush) 179 if (fc->no_flush)
167 return 0; 180 return 0;
168 181
@@ -199,6 +212,9 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
199 struct fuse_fsync_in inarg; 212 struct fuse_fsync_in inarg;
200 int err; 213 int err;
201 214
215 if (is_bad_inode(inode))
216 return -EIO;
217
202 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) 218 if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
203 return 0; 219 return 0;
204 220
@@ -234,54 +250,57 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
234 return fuse_fsync_common(file, de, datasync, 0); 250 return fuse_fsync_common(file, de, datasync, 0);
235} 251}
236 252
237size_t fuse_send_read_common(struct fuse_req *req, struct file *file, 253void fuse_read_fill(struct fuse_req *req, struct file *file,
238 struct inode *inode, loff_t pos, size_t count, 254 struct inode *inode, loff_t pos, size_t count, int opcode)
239 int isdir)
240{ 255{
241 struct fuse_conn *fc = get_fuse_conn(inode);
242 struct fuse_file *ff = file->private_data; 256 struct fuse_file *ff = file->private_data;
243 struct fuse_read_in inarg; 257 struct fuse_read_in *inarg = &req->misc.read_in;
244 258
245 memset(&inarg, 0, sizeof(struct fuse_read_in)); 259 inarg->fh = ff->fh;
246 inarg.fh = ff->fh; 260 inarg->offset = pos;
247 inarg.offset = pos; 261 inarg->size = count;
248 inarg.size = count; 262 req->in.h.opcode = opcode;
249 req->in.h.opcode = isdir ? FUSE_READDIR : FUSE_READ;
250 req->in.h.nodeid = get_node_id(inode); 263 req->in.h.nodeid = get_node_id(inode);
251 req->inode = inode; 264 req->inode = inode;
252 req->file = file; 265 req->file = file;
253 req->in.numargs = 1; 266 req->in.numargs = 1;
254 req->in.args[0].size = sizeof(struct fuse_read_in); 267 req->in.args[0].size = sizeof(struct fuse_read_in);
255 req->in.args[0].value = &inarg; 268 req->in.args[0].value = inarg;
256 req->out.argpages = 1; 269 req->out.argpages = 1;
257 req->out.argvar = 1; 270 req->out.argvar = 1;
258 req->out.numargs = 1; 271 req->out.numargs = 1;
259 req->out.args[0].size = count; 272 req->out.args[0].size = count;
260 request_send(fc, req);
261 return req->out.args[0].size;
262} 273}
263 274
264static inline size_t fuse_send_read(struct fuse_req *req, struct file *file, 275static size_t fuse_send_read(struct fuse_req *req, struct file *file,
265 struct inode *inode, loff_t pos, 276 struct inode *inode, loff_t pos, size_t count)
266 size_t count)
267{ 277{
268 return fuse_send_read_common(req, file, inode, pos, count, 0); 278 struct fuse_conn *fc = get_fuse_conn(inode);
279 fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
280 request_send(fc, req);
281 return req->out.args[0].size;
269} 282}
270 283
271static int fuse_readpage(struct file *file, struct page *page) 284static int fuse_readpage(struct file *file, struct page *page)
272{ 285{
273 struct inode *inode = page->mapping->host; 286 struct inode *inode = page->mapping->host;
274 struct fuse_conn *fc = get_fuse_conn(inode); 287 struct fuse_conn *fc = get_fuse_conn(inode);
275 loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT; 288 struct fuse_req *req;
276 struct fuse_req *req = fuse_get_request(fc); 289 int err;
277 int err = -EINTR; 290
291 err = -EIO;
292 if (is_bad_inode(inode))
293 goto out;
294
295 err = -EINTR;
296 req = fuse_get_request(fc);
278 if (!req) 297 if (!req)
279 goto out; 298 goto out;
280 299
281 req->out.page_zeroing = 1; 300 req->out.page_zeroing = 1;
282 req->num_pages = 1; 301 req->num_pages = 1;
283 req->pages[0] = page; 302 req->pages[0] = page;
284 fuse_send_read(req, file, inode, pos, PAGE_CACHE_SIZE); 303 fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE);
285 err = req->out.h.error; 304 err = req->out.h.error;
286 fuse_put_request(fc, req); 305 fuse_put_request(fc, req);
287 if (!err) 306 if (!err)
@@ -292,21 +311,33 @@ static int fuse_readpage(struct file *file, struct page *page)
292 return err; 311 return err;
293} 312}
294 313
295static int fuse_send_readpages(struct fuse_req *req, struct file *file, 314static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
296 struct inode *inode)
297{ 315{
298 loff_t pos = (loff_t) req->pages[0]->index << PAGE_CACHE_SHIFT; 316 int i;
299 size_t count = req->num_pages << PAGE_CACHE_SHIFT; 317
300 unsigned i; 318 fuse_invalidate_attr(req->pages[0]->mapping->host); /* atime changed */
301 req->out.page_zeroing = 1; 319
302 fuse_send_read(req, file, inode, pos, count);
303 for (i = 0; i < req->num_pages; i++) { 320 for (i = 0; i < req->num_pages; i++) {
304 struct page *page = req->pages[i]; 321 struct page *page = req->pages[i];
305 if (!req->out.h.error) 322 if (!req->out.h.error)
306 SetPageUptodate(page); 323 SetPageUptodate(page);
324 else
325 SetPageError(page);
307 unlock_page(page); 326 unlock_page(page);
308 } 327 }
309 return req->out.h.error; 328 fuse_put_request(fc, req);
329}
330
331static void fuse_send_readpages(struct fuse_req *req, struct file *file,
332 struct inode *inode)
333{
334 struct fuse_conn *fc = get_fuse_conn(inode);
335 loff_t pos = page_offset(req->pages[0]);
336 size_t count = req->num_pages << PAGE_CACHE_SHIFT;
337 req->out.page_zeroing = 1;
338 req->end = fuse_readpages_end;
339 fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
340 request_send_background(fc, req);
310} 341}
311 342
312struct fuse_readpages_data { 343struct fuse_readpages_data {
@@ -326,12 +357,12 @@ static int fuse_readpages_fill(void *_data, struct page *page)
326 (req->num_pages == FUSE_MAX_PAGES_PER_REQ || 357 (req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
327 (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || 358 (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
328 req->pages[req->num_pages - 1]->index + 1 != page->index)) { 359 req->pages[req->num_pages - 1]->index + 1 != page->index)) {
329 int err = fuse_send_readpages(req, data->file, inode); 360 fuse_send_readpages(req, data->file, inode);
330 if (err) { 361 data->req = req = fuse_get_request(fc);
362 if (!req) {
331 unlock_page(page); 363 unlock_page(page);
332 return err; 364 return -EINTR;
333 } 365 }
334 fuse_reset_request(req);
335 } 366 }
336 req->pages[req->num_pages] = page; 367 req->pages[req->num_pages] = page;
337 req->num_pages ++; 368 req->num_pages ++;
@@ -345,6 +376,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
345 struct fuse_conn *fc = get_fuse_conn(inode); 376 struct fuse_conn *fc = get_fuse_conn(inode);
346 struct fuse_readpages_data data; 377 struct fuse_readpages_data data;
347 int err; 378 int err;
379
380 if (is_bad_inode(inode))
381 return -EIO;
382
348 data.file = file; 383 data.file = file;
349 data.inode = inode; 384 data.inode = inode;
350 data.req = fuse_get_request(fc); 385 data.req = fuse_get_request(fc);
@@ -352,10 +387,8 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
352 return -EINTR; 387 return -EINTR;
353 388
354 err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); 389 err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
355 if (!err && data.req->num_pages) 390 if (!err)
356 err = fuse_send_readpages(data.req, file, inode); 391 fuse_send_readpages(data.req, file, inode);
357 fuse_put_request(fc, data.req);
358 fuse_invalidate_attr(inode); /* atime changed */
359 return err; 392 return err;
360} 393}
361 394
@@ -402,8 +435,13 @@ static int fuse_commit_write(struct file *file, struct page *page,
402 unsigned count = to - offset; 435 unsigned count = to - offset;
403 struct inode *inode = page->mapping->host; 436 struct inode *inode = page->mapping->host;
404 struct fuse_conn *fc = get_fuse_conn(inode); 437 struct fuse_conn *fc = get_fuse_conn(inode);
405 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset; 438 loff_t pos = page_offset(page) + offset;
406 struct fuse_req *req = fuse_get_request(fc); 439 struct fuse_req *req;
440
441 if (is_bad_inode(inode))
442 return -EIO;
443
444 req = fuse_get_request(fc);
407 if (!req) 445 if (!req)
408 return -EINTR; 446 return -EINTR;
409 447
@@ -454,7 +492,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
454 492
455 nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT); 493 nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
456 npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 494 npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
457 npages = min(npages, FUSE_MAX_PAGES_PER_REQ); 495 npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ);
458 down_read(&current->mm->mmap_sem); 496 down_read(&current->mm->mmap_sem);
459 npages = get_user_pages(current, current->mm, user_addr, npages, write, 497 npages = get_user_pages(current, current->mm, user_addr, npages, write,
460 0, req->pages, NULL); 498 0, req->pages, NULL);
@@ -475,12 +513,16 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
475 size_t nmax = write ? fc->max_write : fc->max_read; 513 size_t nmax = write ? fc->max_write : fc->max_read;
476 loff_t pos = *ppos; 514 loff_t pos = *ppos;
477 ssize_t res = 0; 515 ssize_t res = 0;
478 struct fuse_req *req = fuse_get_request(fc); 516 struct fuse_req *req;
517
518 if (is_bad_inode(inode))
519 return -EIO;
520
521 req = fuse_get_request(fc);
479 if (!req) 522 if (!req)
480 return -EINTR; 523 return -EINTR;
481 524
482 while (count) { 525 while (count) {
483 size_t tmp;
484 size_t nres; 526 size_t nres;
485 size_t nbytes = min(count, nmax); 527 size_t nbytes = min(count, nmax);
486 int err = fuse_get_user_pages(req, buf, nbytes, !write); 528 int err = fuse_get_user_pages(req, buf, nbytes, !write);
@@ -488,8 +530,8 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
488 res = err; 530 res = err;
489 break; 531 break;
490 } 532 }
491 tmp = (req->num_pages << PAGE_SHIFT) - req->page_offset; 533 nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
492 nbytes = min(nbytes, tmp); 534 nbytes = min(count, nbytes);
493 if (write) 535 if (write)
494 nres = fuse_send_write(req, file, inode, pos, nbytes); 536 nres = fuse_send_write(req, file, inode, pos, nbytes);
495 else 537 else
@@ -535,9 +577,9 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
535 struct inode *inode = file->f_dentry->d_inode; 577 struct inode *inode = file->f_dentry->d_inode;
536 ssize_t res; 578 ssize_t res;
537 /* Don't allow parallel writes to the same file */ 579 /* Don't allow parallel writes to the same file */
538 down(&inode->i_sem); 580 mutex_lock(&inode->i_mutex);
539 res = fuse_direct_io(file, buf, count, ppos, 1); 581 res = fuse_direct_io(file, buf, count, ppos, 1);
540 up(&inode->i_sem); 582 mutex_unlock(&inode->i_mutex);
541 return res; 583 return res;
542} 584}
543 585