diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-08-12 15:38:56 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-08-12 15:39:04 -0400 |
| commit | f46a6804135795f77d096ab0128f27531c7d051c (patch) | |
| tree | 7cd33f69e3661327739ae4c96e5a8389e7fc912e /fs/fuse | |
| parent | b3e84ffa21f916e3354a12a7f19169c9febe96d0 (diff) | |
| parent | ad41a1e0cab07c5125456e8d38e5b1ab148d04aa (diff) | |
Merge branch 'linus' into perf/urgent
Merge reason: Fix upstream breakage introduced by:
de5d9bf: Move list types from <linux/list.h> to <linux/types.h>.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/fuse')
| -rw-r--r-- | fs/fuse/dev.c | 229 | ||||
| -rw-r--r-- | fs/fuse/dir.c | 19 | ||||
| -rw-r--r-- | fs/fuse/file.c | 2 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 3 | ||||
| -rw-r--r-- | fs/fuse/inode.c | 6 |
5 files changed, 239 insertions, 20 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 9424796d6634..69ad053ffd78 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -239,7 +239,6 @@ static u64 fuse_get_unique(struct fuse_conn *fc) | |||
| 239 | 239 | ||
| 240 | static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | 240 | static void queue_request(struct fuse_conn *fc, struct fuse_req *req) |
| 241 | { | 241 | { |
| 242 | req->in.h.unique = fuse_get_unique(fc); | ||
| 243 | req->in.h.len = sizeof(struct fuse_in_header) + | 242 | req->in.h.len = sizeof(struct fuse_in_header) + |
| 244 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); | 243 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); |
| 245 | list_add_tail(&req->list, &fc->pending); | 244 | list_add_tail(&req->list, &fc->pending); |
| @@ -261,6 +260,7 @@ static void flush_bg_queue(struct fuse_conn *fc) | |||
| 261 | req = list_entry(fc->bg_queue.next, struct fuse_req, list); | 260 | req = list_entry(fc->bg_queue.next, struct fuse_req, list); |
| 262 | list_del(&req->list); | 261 | list_del(&req->list); |
| 263 | fc->active_background++; | 262 | fc->active_background++; |
| 263 | req->in.h.unique = fuse_get_unique(fc); | ||
| 264 | queue_request(fc, req); | 264 | queue_request(fc, req); |
| 265 | } | 265 | } |
| 266 | } | 266 | } |
| @@ -398,6 +398,7 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) | |||
| 398 | else if (fc->conn_error) | 398 | else if (fc->conn_error) |
| 399 | req->out.h.error = -ECONNREFUSED; | 399 | req->out.h.error = -ECONNREFUSED; |
| 400 | else { | 400 | else { |
| 401 | req->in.h.unique = fuse_get_unique(fc); | ||
| 401 | queue_request(fc, req); | 402 | queue_request(fc, req); |
| 402 | /* acquire extra reference, since request is still needed | 403 | /* acquire extra reference, since request is still needed |
| 403 | after request_end() */ | 404 | after request_end() */ |
| @@ -450,6 +451,23 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) | |||
| 450 | } | 451 | } |
| 451 | EXPORT_SYMBOL_GPL(fuse_request_send_background); | 452 | EXPORT_SYMBOL_GPL(fuse_request_send_background); |
| 452 | 453 | ||
| 454 | static int fuse_request_send_notify_reply(struct fuse_conn *fc, | ||
| 455 | struct fuse_req *req, u64 unique) | ||
| 456 | { | ||
| 457 | int err = -ENODEV; | ||
| 458 | |||
| 459 | req->isreply = 0; | ||
| 460 | req->in.h.unique = unique; | ||
| 461 | spin_lock(&fc->lock); | ||
| 462 | if (fc->connected) { | ||
| 463 | queue_request(fc, req); | ||
| 464 | err = 0; | ||
| 465 | } | ||
| 466 | spin_unlock(&fc->lock); | ||
| 467 | |||
| 468 | return err; | ||
| 469 | } | ||
| 470 | |||
| 453 | /* | 471 | /* |
| 454 | * Called under fc->lock | 472 | * Called under fc->lock |
| 455 | * | 473 | * |
| @@ -535,13 +553,13 @@ static void fuse_copy_finish(struct fuse_copy_state *cs) | |||
| 535 | if (!cs->write) { | 553 | if (!cs->write) { |
| 536 | buf->ops->unmap(cs->pipe, buf, cs->mapaddr); | 554 | buf->ops->unmap(cs->pipe, buf, cs->mapaddr); |
| 537 | } else { | 555 | } else { |
| 538 | kunmap_atomic(cs->mapaddr, KM_USER0); | 556 | kunmap(buf->page); |
| 539 | buf->len = PAGE_SIZE - cs->len; | 557 | buf->len = PAGE_SIZE - cs->len; |
| 540 | } | 558 | } |
| 541 | cs->currbuf = NULL; | 559 | cs->currbuf = NULL; |
| 542 | cs->mapaddr = NULL; | 560 | cs->mapaddr = NULL; |
| 543 | } else if (cs->mapaddr) { | 561 | } else if (cs->mapaddr) { |
| 544 | kunmap_atomic(cs->mapaddr, KM_USER0); | 562 | kunmap(cs->pg); |
| 545 | if (cs->write) { | 563 | if (cs->write) { |
| 546 | flush_dcache_page(cs->pg); | 564 | flush_dcache_page(cs->pg); |
| 547 | set_page_dirty_lock(cs->pg); | 565 | set_page_dirty_lock(cs->pg); |
| @@ -572,7 +590,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) | |||
| 572 | 590 | ||
| 573 | BUG_ON(!cs->nr_segs); | 591 | BUG_ON(!cs->nr_segs); |
| 574 | cs->currbuf = buf; | 592 | cs->currbuf = buf; |
| 575 | cs->mapaddr = buf->ops->map(cs->pipe, buf, 1); | 593 | cs->mapaddr = buf->ops->map(cs->pipe, buf, 0); |
| 576 | cs->len = buf->len; | 594 | cs->len = buf->len; |
| 577 | cs->buf = cs->mapaddr + buf->offset; | 595 | cs->buf = cs->mapaddr + buf->offset; |
| 578 | cs->pipebufs++; | 596 | cs->pipebufs++; |
| @@ -592,7 +610,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) | |||
| 592 | buf->len = 0; | 610 | buf->len = 0; |
| 593 | 611 | ||
| 594 | cs->currbuf = buf; | 612 | cs->currbuf = buf; |
| 595 | cs->mapaddr = kmap_atomic(page, KM_USER0); | 613 | cs->mapaddr = kmap(page); |
| 596 | cs->buf = cs->mapaddr; | 614 | cs->buf = cs->mapaddr; |
| 597 | cs->len = PAGE_SIZE; | 615 | cs->len = PAGE_SIZE; |
| 598 | cs->pipebufs++; | 616 | cs->pipebufs++; |
| @@ -611,7 +629,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs) | |||
| 611 | return err; | 629 | return err; |
| 612 | BUG_ON(err != 1); | 630 | BUG_ON(err != 1); |
| 613 | offset = cs->addr % PAGE_SIZE; | 631 | offset = cs->addr % PAGE_SIZE; |
| 614 | cs->mapaddr = kmap_atomic(cs->pg, KM_USER0); | 632 | cs->mapaddr = kmap(cs->pg); |
| 615 | cs->buf = cs->mapaddr + offset; | 633 | cs->buf = cs->mapaddr + offset; |
| 616 | cs->len = min(PAGE_SIZE - offset, cs->seglen); | 634 | cs->len = min(PAGE_SIZE - offset, cs->seglen); |
| 617 | cs->seglen -= cs->len; | 635 | cs->seglen -= cs->len; |
| @@ -1231,6 +1249,199 @@ err: | |||
| 1231 | return err; | 1249 | return err; |
| 1232 | } | 1250 | } |
| 1233 | 1251 | ||
| 1252 | static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, | ||
| 1253 | struct fuse_copy_state *cs) | ||
| 1254 | { | ||
| 1255 | struct fuse_notify_store_out outarg; | ||
| 1256 | struct inode *inode; | ||
| 1257 | struct address_space *mapping; | ||
| 1258 | u64 nodeid; | ||
| 1259 | int err; | ||
| 1260 | pgoff_t index; | ||
| 1261 | unsigned int offset; | ||
| 1262 | unsigned int num; | ||
| 1263 | loff_t file_size; | ||
| 1264 | loff_t end; | ||
| 1265 | |||
| 1266 | err = -EINVAL; | ||
| 1267 | if (size < sizeof(outarg)) | ||
| 1268 | goto out_finish; | ||
| 1269 | |||
| 1270 | err = fuse_copy_one(cs, &outarg, sizeof(outarg)); | ||
| 1271 | if (err) | ||
| 1272 | goto out_finish; | ||
| 1273 | |||
| 1274 | err = -EINVAL; | ||
| 1275 | if (size - sizeof(outarg) != outarg.size) | ||
| 1276 | goto out_finish; | ||
| 1277 | |||
| 1278 | nodeid = outarg.nodeid; | ||
| 1279 | |||
| 1280 | down_read(&fc->killsb); | ||
| 1281 | |||
| 1282 | err = -ENOENT; | ||
| 1283 | if (!fc->sb) | ||
| 1284 | goto out_up_killsb; | ||
| 1285 | |||
| 1286 | inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); | ||
| 1287 | if (!inode) | ||
| 1288 | goto out_up_killsb; | ||
| 1289 | |||
| 1290 | mapping = inode->i_mapping; | ||
| 1291 | index = outarg.offset >> PAGE_CACHE_SHIFT; | ||
| 1292 | offset = outarg.offset & ~PAGE_CACHE_MASK; | ||
| 1293 | file_size = i_size_read(inode); | ||
| 1294 | end = outarg.offset + outarg.size; | ||
| 1295 | if (end > file_size) { | ||
| 1296 | file_size = end; | ||
| 1297 | fuse_write_update_size(inode, file_size); | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | num = outarg.size; | ||
| 1301 | while (num) { | ||
| 1302 | struct page *page; | ||
| 1303 | unsigned int this_num; | ||
| 1304 | |||
| 1305 | err = -ENOMEM; | ||
| 1306 | page = find_or_create_page(mapping, index, | ||
| 1307 | mapping_gfp_mask(mapping)); | ||
| 1308 | if (!page) | ||
| 1309 | goto out_iput; | ||
| 1310 | |||
| 1311 | this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); | ||
| 1312 | err = fuse_copy_page(cs, &page, offset, this_num, 0); | ||
| 1313 | if (!err && offset == 0 && (num != 0 || file_size == end)) | ||
| 1314 | SetPageUptodate(page); | ||
| 1315 | unlock_page(page); | ||
| 1316 | page_cache_release(page); | ||
| 1317 | |||
| 1318 | if (err) | ||
| 1319 | goto out_iput; | ||
| 1320 | |||
| 1321 | num -= this_num; | ||
| 1322 | offset = 0; | ||
| 1323 | index++; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | err = 0; | ||
| 1327 | |||
| 1328 | out_iput: | ||
| 1329 | iput(inode); | ||
| 1330 | out_up_killsb: | ||
| 1331 | up_read(&fc->killsb); | ||
| 1332 | out_finish: | ||
| 1333 | fuse_copy_finish(cs); | ||
| 1334 | return err; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) | ||
| 1338 | { | ||
| 1339 | int i; | ||
| 1340 | |||
| 1341 | for (i = 0; i < req->num_pages; i++) { | ||
| 1342 | struct page *page = req->pages[i]; | ||
| 1343 | page_cache_release(page); | ||
| 1344 | } | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | ||
| 1348 | struct fuse_notify_retrieve_out *outarg) | ||
| 1349 | { | ||
| 1350 | int err; | ||
| 1351 | struct address_space *mapping = inode->i_mapping; | ||
| 1352 | struct fuse_req *req; | ||
| 1353 | pgoff_t index; | ||
| 1354 | loff_t file_size; | ||
| 1355 | unsigned int num; | ||
| 1356 | unsigned int offset; | ||
| 1357 | size_t total_len; | ||
| 1358 | |||
| 1359 | req = fuse_get_req(fc); | ||
| 1360 | if (IS_ERR(req)) | ||
| 1361 | return PTR_ERR(req); | ||
| 1362 | |||
| 1363 | offset = outarg->offset & ~PAGE_CACHE_MASK; | ||
| 1364 | |||
| 1365 | req->in.h.opcode = FUSE_NOTIFY_REPLY; | ||
| 1366 | req->in.h.nodeid = outarg->nodeid; | ||
| 1367 | req->in.numargs = 2; | ||
| 1368 | req->in.argpages = 1; | ||
| 1369 | req->page_offset = offset; | ||
| 1370 | req->end = fuse_retrieve_end; | ||
| 1371 | |||
| 1372 | index = outarg->offset >> PAGE_CACHE_SHIFT; | ||
| 1373 | file_size = i_size_read(inode); | ||
| 1374 | num = outarg->size; | ||
| 1375 | if (outarg->offset > file_size) | ||
| 1376 | num = 0; | ||
| 1377 | else if (outarg->offset + num > file_size) | ||
| 1378 | num = file_size - outarg->offset; | ||
| 1379 | |||
| 1380 | while (num) { | ||
| 1381 | struct page *page; | ||
| 1382 | unsigned int this_num; | ||
| 1383 | |||
| 1384 | page = find_get_page(mapping, index); | ||
| 1385 | if (!page) | ||
| 1386 | break; | ||
| 1387 | |||
| 1388 | this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); | ||
| 1389 | req->pages[req->num_pages] = page; | ||
| 1390 | req->num_pages++; | ||
| 1391 | |||
| 1392 | num -= this_num; | ||
| 1393 | total_len += this_num; | ||
| 1394 | } | ||
| 1395 | req->misc.retrieve_in.offset = outarg->offset; | ||
| 1396 | req->misc.retrieve_in.size = total_len; | ||
| 1397 | req->in.args[0].size = sizeof(req->misc.retrieve_in); | ||
| 1398 | req->in.args[0].value = &req->misc.retrieve_in; | ||
| 1399 | req->in.args[1].size = total_len; | ||
| 1400 | |||
| 1401 | err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); | ||
| 1402 | if (err) | ||
| 1403 | fuse_retrieve_end(fc, req); | ||
| 1404 | |||
| 1405 | return err; | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, | ||
| 1409 | struct fuse_copy_state *cs) | ||
| 1410 | { | ||
| 1411 | struct fuse_notify_retrieve_out outarg; | ||
| 1412 | struct inode *inode; | ||
| 1413 | int err; | ||
| 1414 | |||
| 1415 | err = -EINVAL; | ||
| 1416 | if (size != sizeof(outarg)) | ||
| 1417 | goto copy_finish; | ||
| 1418 | |||
| 1419 | err = fuse_copy_one(cs, &outarg, sizeof(outarg)); | ||
| 1420 | if (err) | ||
| 1421 | goto copy_finish; | ||
| 1422 | |||
| 1423 | fuse_copy_finish(cs); | ||
| 1424 | |||
| 1425 | down_read(&fc->killsb); | ||
| 1426 | err = -ENOENT; | ||
| 1427 | if (fc->sb) { | ||
| 1428 | u64 nodeid = outarg.nodeid; | ||
| 1429 | |||
| 1430 | inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); | ||
| 1431 | if (inode) { | ||
| 1432 | err = fuse_retrieve(fc, inode, &outarg); | ||
| 1433 | iput(inode); | ||
| 1434 | } | ||
| 1435 | } | ||
| 1436 | up_read(&fc->killsb); | ||
| 1437 | |||
| 1438 | return err; | ||
| 1439 | |||
| 1440 | copy_finish: | ||
| 1441 | fuse_copy_finish(cs); | ||
| 1442 | return err; | ||
| 1443 | } | ||
| 1444 | |||
| 1234 | static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, | 1445 | static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, |
| 1235 | unsigned int size, struct fuse_copy_state *cs) | 1446 | unsigned int size, struct fuse_copy_state *cs) |
| 1236 | { | 1447 | { |
| @@ -1244,6 +1455,12 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, | |||
| 1244 | case FUSE_NOTIFY_INVAL_ENTRY: | 1455 | case FUSE_NOTIFY_INVAL_ENTRY: |
| 1245 | return fuse_notify_inval_entry(fc, size, cs); | 1456 | return fuse_notify_inval_entry(fc, size, cs); |
| 1246 | 1457 | ||
| 1458 | case FUSE_NOTIFY_STORE: | ||
| 1459 | return fuse_notify_store(fc, size, cs); | ||
| 1460 | |||
| 1461 | case FUSE_NOTIFY_RETRIEVE: | ||
| 1462 | return fuse_notify_retrieve(fc, size, cs); | ||
| 1463 | |||
| 1247 | default: | 1464 | default: |
| 1248 | fuse_copy_finish(cs); | 1465 | fuse_copy_finish(cs); |
| 1249 | return -EINVAL; | 1466 | return -EINVAL; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 3cdc5f78a406..c9627c95482d 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -1016,7 +1016,7 @@ static int fuse_permission(struct inode *inode, int mask) | |||
| 1016 | exist. So if permissions are revoked this won't be | 1016 | exist. So if permissions are revoked this won't be |
| 1017 | noticed immediately, only after the attribute | 1017 | noticed immediately, only after the attribute |
| 1018 | timeout has expired */ | 1018 | timeout has expired */ |
| 1019 | } else if (mask & MAY_ACCESS) { | 1019 | } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { |
| 1020 | err = fuse_access(inode, mask); | 1020 | err = fuse_access(inode, mask); |
| 1021 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { | 1021 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { |
| 1022 | if (!(inode->i_mode & S_IXUGO)) { | 1022 | if (!(inode->i_mode & S_IXUGO)) { |
| @@ -1270,21 +1270,18 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, | |||
| 1270 | if (!fuse_allow_task(fc, current)) | 1270 | if (!fuse_allow_task(fc, current)) |
| 1271 | return -EACCES; | 1271 | return -EACCES; |
| 1272 | 1272 | ||
| 1273 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | 1273 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) |
| 1274 | err = inode_change_ok(inode, attr); | 1274 | attr->ia_valid |= ATTR_FORCE; |
| 1275 | if (err) | 1275 | |
| 1276 | return err; | 1276 | err = inode_change_ok(inode, attr); |
| 1277 | } | 1277 | if (err) |
| 1278 | return err; | ||
| 1278 | 1279 | ||
| 1279 | if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc) | 1280 | if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc) |
| 1280 | return 0; | 1281 | return 0; |
| 1281 | 1282 | ||
| 1282 | if (attr->ia_valid & ATTR_SIZE) { | 1283 | if (attr->ia_valid & ATTR_SIZE) |
| 1283 | err = inode_newsize_ok(inode, attr->ia_size); | ||
| 1284 | if (err) | ||
| 1285 | return err; | ||
| 1286 | is_truncate = true; | 1284 | is_truncate = true; |
| 1287 | } | ||
| 1288 | 1285 | ||
| 1289 | req = fuse_get_req(fc); | 1286 | req = fuse_get_req(fc); |
| 1290 | if (IS_ERR(req)) | 1287 | if (IS_ERR(req)) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index ada0adeb3bb5..147c1f71bdb9 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -706,7 +706,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping, | |||
| 706 | return 0; | 706 | return 0; |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | static void fuse_write_update_size(struct inode *inode, loff_t pos) | 709 | void fuse_write_update_size(struct inode *inode, loff_t pos) |
| 710 | { | 710 | { |
| 711 | struct fuse_conn *fc = get_fuse_conn(inode); | 711 | struct fuse_conn *fc = get_fuse_conn(inode); |
| 712 | struct fuse_inode *fi = get_fuse_inode(inode); | 712 | struct fuse_inode *fi = get_fuse_inode(inode); |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 8f309f04064e..57d4a3a0f102 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -272,6 +272,7 @@ struct fuse_req { | |||
| 272 | struct fuse_write_in in; | 272 | struct fuse_write_in in; |
| 273 | struct fuse_write_out out; | 273 | struct fuse_write_out out; |
| 274 | } write; | 274 | } write; |
| 275 | struct fuse_notify_retrieve_in retrieve_in; | ||
| 275 | struct fuse_lk_in lk_in; | 276 | struct fuse_lk_in lk_in; |
| 276 | } misc; | 277 | } misc; |
| 277 | 278 | ||
| @@ -748,4 +749,6 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
| 748 | unsigned fuse_file_poll(struct file *file, poll_table *wait); | 749 | unsigned fuse_file_poll(struct file *file, poll_table *wait); |
| 749 | int fuse_dev_release(struct inode *inode, struct file *file); | 750 | int fuse_dev_release(struct inode *inode, struct file *file); |
| 750 | 751 | ||
| 752 | void fuse_write_update_size(struct inode *inode, loff_t pos); | ||
| 753 | |||
| 751 | #endif /* _FS_FUSE_I_H */ | 754 | #endif /* _FS_FUSE_I_H */ |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index ec14d19ce501..da9e6e11374c 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
| @@ -122,8 +122,10 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, | |||
| 122 | fuse_request_send_noreply(fc, req); | 122 | fuse_request_send_noreply(fc, req); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | static void fuse_clear_inode(struct inode *inode) | 125 | static void fuse_evict_inode(struct inode *inode) |
| 126 | { | 126 | { |
| 127 | truncate_inode_pages(&inode->i_data, 0); | ||
| 128 | end_writeback(inode); | ||
| 127 | if (inode->i_sb->s_flags & MS_ACTIVE) { | 129 | if (inode->i_sb->s_flags & MS_ACTIVE) { |
| 128 | struct fuse_conn *fc = get_fuse_conn(inode); | 130 | struct fuse_conn *fc = get_fuse_conn(inode); |
| 129 | struct fuse_inode *fi = get_fuse_inode(inode); | 131 | struct fuse_inode *fi = get_fuse_inode(inode); |
| @@ -736,7 +738,7 @@ static const struct export_operations fuse_export_operations = { | |||
| 736 | static const struct super_operations fuse_super_operations = { | 738 | static const struct super_operations fuse_super_operations = { |
| 737 | .alloc_inode = fuse_alloc_inode, | 739 | .alloc_inode = fuse_alloc_inode, |
| 738 | .destroy_inode = fuse_destroy_inode, | 740 | .destroy_inode = fuse_destroy_inode, |
| 739 | .clear_inode = fuse_clear_inode, | 741 | .evict_inode = fuse_evict_inode, |
| 740 | .drop_inode = generic_delete_inode, | 742 | .drop_inode = generic_delete_inode, |
| 741 | .remount_fs = fuse_remount_fs, | 743 | .remount_fs = fuse_remount_fs, |
| 742 | .put_super = fuse_put_super, | 744 | .put_super = fuse_put_super, |
