aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r--fs/ceph/inode.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 98b6e50bde04..602ccd8e06b7 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -352,6 +352,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
352 for (i = 0; i < CEPH_FILE_MODE_NUM; i++) 352 for (i = 0; i < CEPH_FILE_MODE_NUM; i++)
353 ci->i_nr_by_mode[i] = 0; 353 ci->i_nr_by_mode[i] = 0;
354 354
355 mutex_init(&ci->i_truncate_mutex);
355 ci->i_truncate_seq = 0; 356 ci->i_truncate_seq = 0;
356 ci->i_truncate_size = 0; 357 ci->i_truncate_size = 0;
357 ci->i_truncate_pending = 0; 358 ci->i_truncate_pending = 0;
@@ -463,16 +464,20 @@ int ceph_fill_file_size(struct inode *inode, int issued,
463 dout("truncate_seq %u -> %u\n", 464 dout("truncate_seq %u -> %u\n",
464 ci->i_truncate_seq, truncate_seq); 465 ci->i_truncate_seq, truncate_seq);
465 ci->i_truncate_seq = truncate_seq; 466 ci->i_truncate_seq = truncate_seq;
467
468 /* the MDS should have revoked these caps */
469 WARN_ON_ONCE(issued & (CEPH_CAP_FILE_EXCL |
470 CEPH_CAP_FILE_RD |
471 CEPH_CAP_FILE_WR |
472 CEPH_CAP_FILE_LAZYIO));
466 /* 473 /*
467 * If we hold relevant caps, or in the case where we're 474 * If we hold relevant caps, or in the case where we're
468 * not the only client referencing this file and we 475 * not the only client referencing this file and we
469 * don't hold those caps, then we need to check whether 476 * don't hold those caps, then we need to check whether
470 * the file is either opened or mmaped 477 * the file is either opened or mmaped
471 */ 478 */
472 if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD| 479 if ((issued & (CEPH_CAP_FILE_CACHE|
473 CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER| 480 CEPH_CAP_FILE_BUFFER)) ||
474 CEPH_CAP_FILE_EXCL|
475 CEPH_CAP_FILE_LAZYIO)) ||
476 mapping_mapped(inode->i_mapping) || 481 mapping_mapped(inode->i_mapping) ||
477 __ceph_caps_file_wanted(ci)) { 482 __ceph_caps_file_wanted(ci)) {
478 ci->i_truncate_pending++; 483 ci->i_truncate_pending++;
@@ -1427,18 +1432,20 @@ static void ceph_invalidate_work(struct work_struct *work)
1427 u32 orig_gen; 1432 u32 orig_gen;
1428 int check = 0; 1433 int check = 0;
1429 1434
1435 mutex_lock(&ci->i_truncate_mutex);
1430 spin_lock(&ci->i_ceph_lock); 1436 spin_lock(&ci->i_ceph_lock);
1431 dout("invalidate_pages %p gen %d revoking %d\n", inode, 1437 dout("invalidate_pages %p gen %d revoking %d\n", inode,
1432 ci->i_rdcache_gen, ci->i_rdcache_revoking); 1438 ci->i_rdcache_gen, ci->i_rdcache_revoking);
1433 if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { 1439 if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
1434 /* nevermind! */ 1440 /* nevermind! */
1435 spin_unlock(&ci->i_ceph_lock); 1441 spin_unlock(&ci->i_ceph_lock);
1442 mutex_unlock(&ci->i_truncate_mutex);
1436 goto out; 1443 goto out;
1437 } 1444 }
1438 orig_gen = ci->i_rdcache_gen; 1445 orig_gen = ci->i_rdcache_gen;
1439 spin_unlock(&ci->i_ceph_lock); 1446 spin_unlock(&ci->i_ceph_lock);
1440 1447
1441 truncate_inode_pages(&inode->i_data, 0); 1448 truncate_inode_pages(inode->i_mapping, 0);
1442 1449
1443 spin_lock(&ci->i_ceph_lock); 1450 spin_lock(&ci->i_ceph_lock);
1444 if (orig_gen == ci->i_rdcache_gen && 1451 if (orig_gen == ci->i_rdcache_gen &&
@@ -1453,6 +1460,7 @@ static void ceph_invalidate_work(struct work_struct *work)
1453 ci->i_rdcache_revoking); 1460 ci->i_rdcache_revoking);
1454 } 1461 }
1455 spin_unlock(&ci->i_ceph_lock); 1462 spin_unlock(&ci->i_ceph_lock);
1463 mutex_unlock(&ci->i_truncate_mutex);
1456 1464
1457 if (check) 1465 if (check)
1458 ceph_check_caps(ci, 0, NULL); 1466 ceph_check_caps(ci, 0, NULL);
@@ -1473,16 +1481,7 @@ static void ceph_vmtruncate_work(struct work_struct *work)
1473 struct inode *inode = &ci->vfs_inode; 1481 struct inode *inode = &ci->vfs_inode;
1474 1482
1475 dout("vmtruncate_work %p\n", inode); 1483 dout("vmtruncate_work %p\n", inode);
1476 if (!mutex_trylock(&inode->i_mutex)) {
1477 /*
1478 * the i_mutex can be hold by a writer who is waiting for
1479 * caps. wake up waiters, they will do pending vmtruncate.
1480 */
1481 wake_up_all(&ci->i_cap_wq);
1482 mutex_lock(&inode->i_mutex);
1483 }
1484 __ceph_do_pending_vmtruncate(inode); 1484 __ceph_do_pending_vmtruncate(inode);
1485 mutex_unlock(&inode->i_mutex);
1486 iput(inode); 1485 iput(inode);
1487} 1486}
1488 1487
@@ -1515,11 +1514,13 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
1515 u64 to; 1514 u64 to;
1516 int wrbuffer_refs, finish = 0; 1515 int wrbuffer_refs, finish = 0;
1517 1516
1517 mutex_lock(&ci->i_truncate_mutex);
1518retry: 1518retry:
1519 spin_lock(&ci->i_ceph_lock); 1519 spin_lock(&ci->i_ceph_lock);
1520 if (ci->i_truncate_pending == 0) { 1520 if (ci->i_truncate_pending == 0) {
1521 dout("__do_pending_vmtruncate %p none pending\n", inode); 1521 dout("__do_pending_vmtruncate %p none pending\n", inode);
1522 spin_unlock(&ci->i_ceph_lock); 1522 spin_unlock(&ci->i_ceph_lock);
1523 mutex_unlock(&ci->i_truncate_mutex);
1523 return; 1524 return;
1524 } 1525 }
1525 1526
@@ -1536,6 +1537,9 @@ retry:
1536 goto retry; 1537 goto retry;
1537 } 1538 }
1538 1539
1540 /* there should be no reader or writer */
1541 WARN_ON_ONCE(ci->i_rd_ref || ci->i_wr_ref);
1542
1539 to = ci->i_truncate_size; 1543 to = ci->i_truncate_size;
1540 wrbuffer_refs = ci->i_wrbuffer_ref; 1544 wrbuffer_refs = ci->i_wrbuffer_ref;
1541 dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode, 1545 dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode,
@@ -1553,6 +1557,8 @@ retry:
1553 if (!finish) 1557 if (!finish)
1554 goto retry; 1558 goto retry;
1555 1559
1560 mutex_unlock(&ci->i_truncate_mutex);
1561
1556 if (wrbuffer_refs == 0) 1562 if (wrbuffer_refs == 0)
1557 ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); 1563 ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
1558 1564
@@ -1601,8 +1607,6 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
1601 if (ceph_snap(inode) != CEPH_NOSNAP) 1607 if (ceph_snap(inode) != CEPH_NOSNAP)
1602 return -EROFS; 1608 return -EROFS;
1603 1609
1604 __ceph_do_pending_vmtruncate(inode);
1605
1606 err = inode_change_ok(inode, attr); 1610 err = inode_change_ok(inode, attr);
1607 if (err != 0) 1611 if (err != 0)
1608 return err; 1612 return err;
@@ -1783,7 +1787,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
1783 ceph_cap_string(dirtied), mask); 1787 ceph_cap_string(dirtied), mask);
1784 1788
1785 ceph_mdsc_put_request(req); 1789 ceph_mdsc_put_request(req);
1786 __ceph_do_pending_vmtruncate(inode); 1790 if (mask & CEPH_SETATTR_SIZE)
1791 __ceph_do_pending_vmtruncate(inode);
1787 return err; 1792 return err;
1788out: 1793out:
1789 spin_unlock(&ci->i_ceph_lock); 1794 spin_unlock(&ci->i_ceph_lock);