All of lore.kernel.org
 help / color / mirror / Atom feed
* ceph: Check PagePrivate(page) before dereference, page->private
@ 2012-05-25  9:15 Yan, Zheng
  2012-05-25 16:24 ` Sage Weil
  0 siblings, 1 reply; 3+ messages in thread
From: Yan, Zheng @ 2012-05-25  9:15 UTC (permalink / raw)
  To: ceph-devel

I got lots of NULL pointer dereference Oops when compiling kernel on ceph.
The bug is because the kernel page migration routine replaces some pages
in the page cache with new pages, these new pages' private can be non-zero.

Signed-off-by: Zheng Yan <zheng.z.yan@intel.com>
---
 fs/ceph/addr.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 173b1d2..1f180b1 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -984,7 +984,10 @@ retry_locked:
 	BUG_ON(!ci->i_snap_realm);
 	down_read(&mdsc->snap_rwsem);
 	BUG_ON(!ci->i_snap_realm->cached_context);
-	snapc = (void *)page->private;
+	if (PagePrivate(page))
+		snapc = (void *)page->private;
+	else
+		snapc = NULL;
 	if (snapc && snapc != ci->i_head_snapc) {
 		/*
 		 * this page is already dirty in another (older) snap
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: ceph: Check PagePrivate(page) before dereference, page->private
  2012-05-25  9:15 ceph: Check PagePrivate(page) before dereference, page->private Yan, Zheng
@ 2012-05-25 16:24 ` Sage Weil
  2012-05-28  6:01   ` Yan, Zheng
  0 siblings, 1 reply; 3+ messages in thread
From: Sage Weil @ 2012-05-25 16:24 UTC (permalink / raw)
  To: Yan, Zheng; +Cc: ceph-devel

Hi Yan,

On Fri, 25 May 2012, Yan, Zheng wrote:
> I got lots of NULL pointer dereference Oops when compiling kernel on ceph.
> The bug is because the kernel page migration routine replaces some pages
> in the page cache with new pages, these new pages' private can be non-zero.
> 
> Signed-off-by: Zheng Yan <zheng.z.yan@intel.com>
> ---
>  fs/ceph/addr.c |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index 173b1d2..1f180b1 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -984,7 +984,10 @@ retry_locked:
>  	BUG_ON(!ci->i_snap_realm);
>  	down_read(&mdsc->snap_rwsem);
>  	BUG_ON(!ci->i_snap_realm->cached_context);
> -	snapc = (void *)page->private;
> +	if (PagePrivate(page))
> +		snapc = (void *)page->private;
> +	else
> +		snapc = NULL;
>  	if (snapc && snapc != ci->i_head_snapc) {
>  		/*
>  		 * this page is already dirty in another (older) snap
> -- 

This looks right for this case.  What I'm less sure about is whether it's 
sufficient.  I take it the migration only happens on clean pages?  (Unless 
->migrate is implemented?)

Before we were assuming private == NULL on any clean page, independent of 
PG_private.  For example, ceph_invalidatepage() and ceph_releasepage() 
have BUG_ONs that are probably wrong.  writepage_nounlock() has a sanity 
check that should probably be strengthened/guarded with a PagePrivate() 
check, too.

sage

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: ceph: Check PagePrivate(page) before dereference, page->private
  2012-05-25 16:24 ` Sage Weil
@ 2012-05-28  6:01   ` Yan, Zheng
  0 siblings, 0 replies; 3+ messages in thread
From: Yan, Zheng @ 2012-05-28  6:01 UTC (permalink / raw)
  To: Sage Weil; +Cc: ceph-devel

On 05/26/2012 12:24 AM, Sage Weil wrote:
> Hi Yan,
> 
> On Fri, 25 May 2012, Yan, Zheng wrote:
>> I got lots of NULL pointer dereference Oops when compiling kernel on ceph.
>> The bug is because the kernel page migration routine replaces some pages
>> in the page cache with new pages, these new pages' private can be non-zero.
>>
>> Signed-off-by: Zheng Yan <zheng.z.yan@intel.com>
>> ---
>>  fs/ceph/addr.c |    5 ++++-
>>  1 files changed, 4 insertions(+), 1 deletions(-)
>>
>> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
>> index 173b1d2..1f180b1 100644
>> --- a/fs/ceph/addr.c
>> +++ b/fs/ceph/addr.c
>> @@ -984,7 +984,10 @@ retry_locked:
>>  	BUG_ON(!ci->i_snap_realm);
>>  	down_read(&mdsc->snap_rwsem);
>>  	BUG_ON(!ci->i_snap_realm->cached_context);
>> -	snapc = (void *)page->private;
>> +	if (PagePrivate(page))
>> +		snapc = (void *)page->private;
>> +	else
>> +		snapc = NULL;
>>  	if (snapc && snapc != ci->i_head_snapc) {
>>  		/*
>>  		 * this page is already dirty in another (older) snap
>> -- 
> 
> This looks right for this case.  What I'm less sure about is whether it's 
> sufficient.  I take it the migration only happens on clean pages?  (Unless 
> ->migrate is implemented?)
Yes, migration only happens on pages that are clean and have no private
stuff.

> 
> Before we were assuming private == NULL on any clean page, independent of 
> PG_private.  For example, ceph_invalidatepage() and ceph_releasepage() 
> have BUG_ONs that are probably wrong.  writepage_nounlock() has a sanity 
> check that should probably be strengthened/guarded with a PagePrivate() 
> check, too.
>
Will send the v2 patch soon.

Regards
Yan, Zheng


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-05-28  6:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-25  9:15 ceph: Check PagePrivate(page) before dereference, page->private Yan, Zheng
2012-05-25 16:24 ` Sage Weil
2012-05-28  6:01   ` Yan, Zheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.