aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/addr.c3
-rw-r--r--fs/ceph/caps.c25
-rw-r--r--fs/ceph/inode.c61
-rw-r--r--fs/ceph/super.h19
4 files changed, 65 insertions, 43 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 89c5ff3b59d5..71f5ad1c1e26 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -947,8 +947,7 @@ retry_locked:
947 */ 947 */
948 snapc = ceph_get_snap_context((void *)page->private); 948 snapc = ceph_get_snap_context((void *)page->private);
949 unlock_page(page); 949 unlock_page(page);
950 if (ceph_queue_writeback(inode)) 950 ceph_queue_writeback(inode);
951 igrab(inode);
952 wait_event_interruptible(ci->i_cap_wq, 951 wait_event_interruptible(ci->i_cap_wq,
953 context_is_writeable_or_written(inode, snapc)); 952 context_is_writeable_or_written(inode, snapc));
954 ceph_put_snap_context(snapc); 953 ceph_put_snap_context(snapc);
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 7f4841cd3a2b..68ee78109224 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1602,8 +1602,7 @@ ack:
1602 spin_unlock(&inode->i_lock); 1602 spin_unlock(&inode->i_lock);
1603 1603
1604 if (queue_invalidate) 1604 if (queue_invalidate)
1605 if (ceph_queue_page_invalidation(inode)) 1605 ceph_queue_invalidate(inode);
1606 igrab(inode);
1607 1606
1608 if (session && drop_session_lock) 1607 if (session && drop_session_lock)
1609 mutex_unlock(&session->s_mutex); 1608 mutex_unlock(&session->s_mutex);
@@ -2178,7 +2177,7 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2178 int wake = 0; 2177 int wake = 0;
2179 int writeback = 0; 2178 int writeback = 0;
2180 int revoked_rdcache = 0; 2179 int revoked_rdcache = 0;
2181 int invalidate_async = 0; 2180 int queue_invalidate = 0;
2182 int tried_invalidate = 0; 2181 int tried_invalidate = 0;
2183 int ret; 2182 int ret;
2184 2183
@@ -2205,7 +2204,7 @@ restart:
2205 /* there were locked pages.. invalidate later 2204 /* there were locked pages.. invalidate later
2206 in a separate thread. */ 2205 in a separate thread. */
2207 if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { 2206 if (ci->i_rdcache_revoking != ci->i_rdcache_gen) {
2208 invalidate_async = 1; 2207 queue_invalidate = 1;
2209 ci->i_rdcache_revoking = ci->i_rdcache_gen; 2208 ci->i_rdcache_revoking = ci->i_rdcache_gen;
2210 } 2209 }
2211 } else { 2210 } else {
@@ -2319,21 +2318,15 @@ restart:
2319 } 2318 }
2320 2319
2321 spin_unlock(&inode->i_lock); 2320 spin_unlock(&inode->i_lock);
2322 if (writeback) { 2321 if (writeback)
2323 /* 2322 /*
2324 * queue inode for writeback: we can't actually call 2323 * queue inode for writeback: we can't actually call
2325 * filemap_write_and_wait, etc. from message handler 2324 * filemap_write_and_wait, etc. from message handler
2326 * context. 2325 * context.
2327 */ 2326 */
2328 dout("queueing %p for writeback\n", inode); 2327 ceph_queue_writeback(inode);
2329 if (ceph_queue_writeback(inode)) 2328 if (queue_invalidate)
2330 igrab(inode); 2329 ceph_queue_invalidate(inode);
2331 }
2332 if (invalidate_async) {
2333 dout("queueing %p for page invalidation\n", inode);
2334 if (ceph_queue_page_invalidation(inode))
2335 igrab(inode);
2336 }
2337 if (wake) 2330 if (wake)
2338 wake_up(&ci->i_cap_wq); 2331 wake_up(&ci->i_cap_wq);
2339 return reply; 2332 return reply;
@@ -2479,9 +2472,7 @@ static void handle_cap_trunc(struct inode *inode,
2479 spin_unlock(&inode->i_lock); 2472 spin_unlock(&inode->i_lock);
2480 2473
2481 if (queue_trunc) 2474 if (queue_trunc)
2482 if (queue_work(ceph_client(inode->i_sb)->trunc_wq, 2475 ceph_queue_vmtruncate(inode);
2483 &ci->i_vmtruncate_work))
2484 igrab(inode);
2485} 2476}
2486 2477
2487/* 2478/*
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index af85f2de2f7c..58bdff09c2c1 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -28,7 +28,9 @@
28 28
29static const struct inode_operations ceph_symlink_iops; 29static const struct inode_operations ceph_symlink_iops;
30 30
31static void ceph_inode_invalidate_pages(struct work_struct *work); 31static void ceph_invalidate_work(struct work_struct *work);
32static void ceph_writeback_work(struct work_struct *work);
33static void ceph_vmtruncate_work(struct work_struct *work);
32 34
33/* 35/*
34 * find or create an inode, given the ceph ino number 36 * find or create an inode, given the ceph ino number
@@ -357,8 +359,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
357 INIT_LIST_HEAD(&ci->i_snap_realm_item); 359 INIT_LIST_HEAD(&ci->i_snap_realm_item);
358 INIT_LIST_HEAD(&ci->i_snap_flush_item); 360 INIT_LIST_HEAD(&ci->i_snap_flush_item);
359 361
360 INIT_WORK(&ci->i_wb_work, ceph_inode_writeback); 362 INIT_WORK(&ci->i_wb_work, ceph_writeback_work);
361 INIT_WORK(&ci->i_pg_inv_work, ceph_inode_invalidate_pages); 363 INIT_WORK(&ci->i_pg_inv_work, ceph_invalidate_work);
362 364
363 INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work); 365 INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work);
364 366
@@ -675,9 +677,7 @@ no_change:
675 677
676 /* queue truncate if we saw i_size decrease */ 678 /* queue truncate if we saw i_size decrease */
677 if (queue_trunc) 679 if (queue_trunc)
678 if (queue_work(ceph_client(inode->i_sb)->trunc_wq, 680 ceph_queue_vmtruncate(inode);
679 &ci->i_vmtruncate_work))
680 igrab(inode);
681 681
682 /* populate frag tree */ 682 /* populate frag tree */
683 /* FIXME: move me up, if/when version reflects fragtree changes */ 683 /* FIXME: move me up, if/when version reflects fragtree changes */
@@ -1243,7 +1243,18 @@ int ceph_inode_set_size(struct inode *inode, loff_t size)
1243 * Write back inode data in a worker thread. (This can't be done 1243 * Write back inode data in a worker thread. (This can't be done
1244 * in the message handler context.) 1244 * in the message handler context.)
1245 */ 1245 */
1246void ceph_inode_writeback(struct work_struct *work) 1246void ceph_queue_writeback(struct inode *inode)
1247{
1248 if (queue_work(ceph_inode_to_client(inode)->wb_wq,
1249 &ceph_inode(inode)->i_wb_work)) {
1250 dout("ceph_queue_invalidate %p\n", inode);
1251 igrab(inode);
1252 } else {
1253 dout("ceph_queue_invalidate %p failed\n", inode);
1254 }
1255}
1256
1257static void ceph_writeback_work(struct work_struct *work)
1247{ 1258{
1248 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, 1259 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
1249 i_wb_work); 1260 i_wb_work);
@@ -1255,10 +1266,24 @@ void ceph_inode_writeback(struct work_struct *work)
1255} 1266}
1256 1267
1257/* 1268/*
1269 * queue an async invalidation
1270 */
1271void ceph_queue_invalidate(struct inode *inode)
1272{
1273 if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
1274 &ceph_inode(inode)->i_pg_inv_work)) {
1275 dout("ceph_queue_invalidate %p\n", inode);
1276 igrab(inode);
1277 } else {
1278 dout("ceph_queue_invalidate %p failed\n", inode);
1279 }
1280}
1281
1282/*
1258 * Invalidate inode pages in a worker thread. (This can't be done 1283 * Invalidate inode pages in a worker thread. (This can't be done
1259 * in the message handler context.) 1284 * in the message handler context.)
1260 */ 1285 */
1261static void ceph_inode_invalidate_pages(struct work_struct *work) 1286static void ceph_invalidate_work(struct work_struct *work)
1262{ 1287{
1263 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, 1288 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
1264 i_pg_inv_work); 1289 i_pg_inv_work);
@@ -1307,7 +1332,7 @@ out:
1307 * 1332 *
1308 * We also truncate in a separate thread as well. 1333 * We also truncate in a separate thread as well.
1309 */ 1334 */
1310void ceph_vmtruncate_work(struct work_struct *work) 1335static void ceph_vmtruncate_work(struct work_struct *work)
1311{ 1336{
1312 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, 1337 struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info,
1313 i_vmtruncate_work); 1338 i_vmtruncate_work);
@@ -1321,6 +1346,24 @@ void ceph_vmtruncate_work(struct work_struct *work)
1321} 1346}
1322 1347
1323/* 1348/*
1349 * Queue an async vmtruncate. If we fail to queue work, we will handle
1350 * the truncation the next time we call __ceph_do_pending_vmtruncate.
1351 */
1352void ceph_queue_vmtruncate(struct inode *inode)
1353{
1354 struct ceph_inode_info *ci = ceph_inode(inode);
1355
1356 if (queue_work(ceph_client(inode->i_sb)->trunc_wq,
1357 &ci->i_vmtruncate_work)) {
1358 dout("ceph_queue_vmtruncate %p\n", inode);
1359 igrab(inode);
1360 } else {
1361 dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
1362 inode, ci->i_truncate_pending);
1363 }
1364}
1365
1366/*
1324 * called with i_mutex held. 1367 * called with i_mutex held.
1325 * 1368 *
1326 * Make sure any pending truncation is applied before doing anything 1369 * Make sure any pending truncation is applied before doing anything
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 3930fb685f0b..b2adfccbab98 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -573,18 +573,6 @@ static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb)
573 return (struct ceph_client *)sb->s_fs_info; 573 return (struct ceph_client *)sb->s_fs_info;
574} 574}
575 575
576static inline int ceph_queue_writeback(struct inode *inode)
577{
578 return queue_work(ceph_inode_to_client(inode)->wb_wq,
579 &ceph_inode(inode)->i_wb_work);
580}
581
582static inline int ceph_queue_page_invalidation(struct inode *inode)
583{
584 return queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
585 &ceph_inode(inode)->i_pg_inv_work);
586}
587
588 576
589/* 577/*
590 * we keep buffered readdir results attached to file->private_data 578 * we keep buffered readdir results attached to file->private_data
@@ -772,10 +760,11 @@ extern int ceph_readdir_prepopulate(struct ceph_mds_request *req,
772extern int ceph_inode_holds_cap(struct inode *inode, int mask); 760extern int ceph_inode_holds_cap(struct inode *inode, int mask);
773 761
774extern int ceph_inode_set_size(struct inode *inode, loff_t size); 762extern int ceph_inode_set_size(struct inode *inode, loff_t size);
775extern void ceph_inode_writeback(struct work_struct *work);
776extern void ceph_vmtruncate_work(struct work_struct *work);
777extern void __ceph_do_pending_vmtruncate(struct inode *inode); 763extern void __ceph_do_pending_vmtruncate(struct inode *inode);
778extern void __ceph_queue_vmtruncate(struct inode *inode); 764extern void ceph_queue_vmtruncate(struct inode *inode);
765
766extern void ceph_queue_invalidate(struct inode *inode);
767extern void ceph_queue_writeback(struct inode *inode);
779 768
780extern int ceph_do_getattr(struct inode *inode, int mask); 769extern int ceph_do_getattr(struct inode *inode, int mask);
781extern int ceph_permission(struct inode *inode, int mask); 770extern int ceph_permission(struct inode *inode, int mask);