From 647f6ddef5d260d7d9d641e5f00280439bf7520e Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 13 Nov 2008 11:19:14 -0800 Subject: [PATCH] kclient: grab reference on inode before async operation --- src/kernel/addr.c | 3 ++- src/kernel/caps.c | 14 +++++++++----- src/kernel/inode.c | 6 +++++- src/kernel/super.h | 8 ++++---- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/kernel/addr.c b/src/kernel/addr.c index 9caa8ace0ef72..817fd617e8a61 100644 --- a/src/kernel/addr.c +++ b/src/kernel/addr.c @@ -856,7 +856,8 @@ retry_locked: * to be writeable or written */ snapc = ceph_get_snap_context((void *)page->private); unlock_page(page); - ceph_queue_writeback(inode); + if (ceph_queue_writeback(inode)) + igrab(inode); wait_event_interruptible(ci->i_cap_wq, context_is_writeable_or_written(inode, snapc)); ceph_put_snap_context(snapc); diff --git a/src/kernel/caps.c b/src/kernel/caps.c index ffcd3e87b3316..bdc761e3ae9ec 100644 --- a/src/kernel/caps.c +++ b/src/kernel/caps.c @@ -1091,11 +1091,13 @@ out: * context. */ dout(10, "queueing %p for writeback\n", inode); - ceph_queue_writeback(inode); + if (ceph_queue_writeback(inode)) + igrab(inode); } if (invalidate_async) { dout(10, "queueing %p for page invalidation\n", inode); - ceph_queue_page_invalidation(inode); + if (ceph_queue_page_invalidation(inode)) + igrab(inode); } if (wake) wake_up(&ci->i_cap_wq); @@ -1216,9 +1218,11 @@ static void handle_cap_trunc(struct inode *inode, ci->i_reported_size = size; spin_unlock(&inode->i_lock); - if (queue_trunc) - queue_work(ceph_client(inode->i_sb)->trunc_wq, - &ci->i_vmtruncate_work); + if (queue_trunc) { + if (queue_work(ceph_client(inode->i_sb)->trunc_wq, + &ci->i_vmtruncate_work)) + igrab(inode); + } } /* diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 66306b5af669e..c1d2286c56180 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -1293,6 +1293,7 @@ void ceph_inode_writeback(struct work_struct *work) dout(10, "writeback %p\n", inode); filemap_write_and_wait(&inode->i_data); + iput(inode); } /* @@ -1316,7 +1317,7 @@ static void ceph_inode_invalidate_pages(struct work_struct *work) /* nevermind! */ ci->i_rdcache_revoking = 0; spin_unlock(&inode->i_lock); - return; + goto out; } orig_gen = ci->i_rdcache_gen; spin_unlock(&inode->i_lock); @@ -1338,6 +1339,8 @@ static void ceph_inode_invalidate_pages(struct work_struct *work) if (check) ceph_check_caps(ci, 0); +out: + iput(inode); } @@ -1356,6 +1359,7 @@ void ceph_vmtruncate_work(struct work_struct *work) mutex_lock(&inode->i_mutex); __ceph_do_pending_vmtruncate(inode); mutex_unlock(&inode->i_mutex); + iput(inode); } /* diff --git a/src/kernel/super.h b/src/kernel/super.h index dc806a2d5405f..bdf45d1334038 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -425,15 +425,15 @@ static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb) return (struct ceph_client *)sb->s_fs_info; } -static inline void ceph_queue_writeback(struct inode *inode) +static inline int ceph_queue_writeback(struct inode *inode) { - queue_work(ceph_inode_to_client(inode)->wb_wq, + return queue_work(ceph_inode_to_client(inode)->wb_wq, &ceph_inode(inode)->i_wb_work); } -static inline void ceph_queue_page_invalidation(struct inode *inode) +static inline int ceph_queue_page_invalidation(struct inode *inode) { - queue_work(ceph_inode_to_client(inode)->pg_inv_wq, + return queue_work(ceph_inode_to_client(inode)->pg_inv_wq, &ceph_inode(inode)->i_pg_inv_work); } -- 2.39.5