* [PATCH 0/3] ceph: locking fixes for snaprealm handling @ 2021-06-03 16:52 Jeff Layton 2021-06-03 16:52 ` [PATCH 1/3] ceph: add some lockdep assertions around " Jeff Layton ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Jeff Layton @ 2021-06-03 16:52 UTC (permalink / raw) To: ceph-devel, idryomov The snaprealm handling code has a number of really old and misleading comments that claim that we need certain locks when holding certain functions. Some of them are wrong, and at least one caller is not holding the snap_rwsem when filling an inode. The first patch in this series adds some lockdep annotations that mirror the comments. The second one relaxes the lockdep annotations for a couple of the functions to better conform with the real requirements of the code. The last patch then fixes a bug in async create code and ensures that we're holding the correct locks when filling a new inode. Jeff Layton (3): ceph: add some lockdep assertions around snaprealm handling ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm ceph: must hold snap_rwsem when filling inode for async create fs/ceph/file.c | 3 +++ fs/ceph/inode.c | 2 ++ fs/ceph/snap.c | 20 ++++++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) -- 2.31.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] ceph: add some lockdep assertions around snaprealm handling 2021-06-03 16:52 [PATCH 0/3] ceph: locking fixes for snaprealm handling Jeff Layton @ 2021-06-03 16:52 ` Jeff Layton 2021-06-21 20:05 ` Ilya Dryomov 2021-06-03 16:52 ` [PATCH 2/3] ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm Jeff Layton 2021-06-03 16:52 ` [PATCH 3/3] ceph: must hold snap_rwsem when filling inode for async create Jeff Layton 2 siblings, 1 reply; 9+ messages in thread From: Jeff Layton @ 2021-06-03 16:52 UTC (permalink / raw) To: ceph-devel, idryomov Turn some comments into lockdep asserts. Signed-off-by: Jeff Layton <jlayton@kernel.org> --- fs/ceph/snap.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 2a63fb37778b..bc6c33d485e6 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -65,6 +65,8 @@ void ceph_get_snap_realm(struct ceph_mds_client *mdsc, struct ceph_snap_realm *realm) { + lockdep_assert_held_write(&mdsc->snap_rwsem); + dout("get_realm %p %d -> %d\n", realm, atomic_read(&realm->nref), atomic_read(&realm->nref)+1); /* @@ -113,6 +115,8 @@ static struct ceph_snap_realm *ceph_create_snap_realm( { struct ceph_snap_realm *realm; + lockdep_assert_held_write(&mdsc->snap_rwsem); + realm = kzalloc(sizeof(*realm), GFP_NOFS); if (!realm) return ERR_PTR(-ENOMEM); @@ -143,6 +147,8 @@ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, struct rb_node *n = mdsc->snap_realms.rb_node; struct ceph_snap_realm *r; + lockdep_assert_held_write(&mdsc->snap_rwsem); + while (n) { r = rb_entry(n, struct ceph_snap_realm, node); if (ino < r->ino) @@ -176,6 +182,8 @@ static void __put_snap_realm(struct ceph_mds_client *mdsc, static void __destroy_snap_realm(struct ceph_mds_client *mdsc, struct ceph_snap_realm *realm) { + lockdep_assert_held_write(&mdsc->snap_rwsem); + dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); rb_erase(&realm->node, &mdsc->snap_realms); @@ -198,6 +206,8 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc, static void __put_snap_realm(struct ceph_mds_client *mdsc, struct ceph_snap_realm *realm) { + lockdep_assert_held_write(&mdsc->snap_rwsem); + dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm, atomic_read(&realm->nref), atomic_read(&realm->nref)-1); if (atomic_dec_and_test(&realm->nref)) @@ -236,6 +246,8 @@ static void __cleanup_empty_realms(struct ceph_mds_client *mdsc) { struct ceph_snap_realm *realm; + lockdep_assert_held_write(&mdsc->snap_rwsem); + spin_lock(&mdsc->snap_empty_lock); while (!list_empty(&mdsc->snap_empty)) { realm = list_first_entry(&mdsc->snap_empty, @@ -269,6 +281,8 @@ static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc, { struct ceph_snap_realm *parent; + lockdep_assert_held_write(&mdsc->snap_rwsem); + if (realm->parent_ino == parentino) return 0; @@ -696,6 +710,8 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, int err = -ENOMEM; LIST_HEAD(dirty_realms); + lockdep_assert_held_write(&mdsc->snap_rwsem); + dout("update_snap_trace deletion=%d\n", deletion); more: ceph_decode_need(&p, e, sizeof(*ri), bad); -- 2.31.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] ceph: add some lockdep assertions around snaprealm handling 2021-06-03 16:52 ` [PATCH 1/3] ceph: add some lockdep assertions around " Jeff Layton @ 2021-06-21 20:05 ` Ilya Dryomov 2021-06-21 20:51 ` Jeff Layton 0 siblings, 1 reply; 9+ messages in thread From: Ilya Dryomov @ 2021-06-21 20:05 UTC (permalink / raw) To: Jeff Layton; +Cc: Ceph Development On Thu, Jun 3, 2021 at 6:52 PM Jeff Layton <jlayton@kernel.org> wrote: > > Turn some comments into lockdep asserts. > > Signed-off-by: Jeff Layton <jlayton@kernel.org> > --- > fs/ceph/snap.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c > index 2a63fb37778b..bc6c33d485e6 100644 > --- a/fs/ceph/snap.c > +++ b/fs/ceph/snap.c > @@ -65,6 +65,8 @@ > void ceph_get_snap_realm(struct ceph_mds_client *mdsc, > struct ceph_snap_realm *realm) > { > + lockdep_assert_held_write(&mdsc->snap_rwsem); > + > dout("get_realm %p %d -> %d\n", realm, > atomic_read(&realm->nref), atomic_read(&realm->nref)+1); > /* > @@ -113,6 +115,8 @@ static struct ceph_snap_realm *ceph_create_snap_realm( > { > struct ceph_snap_realm *realm; > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > + > realm = kzalloc(sizeof(*realm), GFP_NOFS); > if (!realm) > return ERR_PTR(-ENOMEM); > @@ -143,6 +147,8 @@ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, > struct rb_node *n = mdsc->snap_realms.rb_node; > struct ceph_snap_realm *r; > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > + > while (n) { > r = rb_entry(n, struct ceph_snap_realm, node); > if (ino < r->ino) > @@ -176,6 +182,8 @@ static void __put_snap_realm(struct ceph_mds_client *mdsc, > static void __destroy_snap_realm(struct ceph_mds_client *mdsc, > struct ceph_snap_realm *realm) > { > + lockdep_assert_held_write(&mdsc->snap_rwsem); > + > dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); > > rb_erase(&realm->node, &mdsc->snap_realms); > @@ -198,6 +206,8 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc, > static void __put_snap_realm(struct ceph_mds_client *mdsc, > struct ceph_snap_realm *realm) > { > + lockdep_assert_held_write(&mdsc->snap_rwsem); This one appears to be redundant since the only caller is __destroy_snap_realm(). > + > dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm, > atomic_read(&realm->nref), atomic_read(&realm->nref)-1); > if (atomic_dec_and_test(&realm->nref)) > @@ -236,6 +246,8 @@ static void __cleanup_empty_realms(struct ceph_mds_client *mdsc) > { > struct ceph_snap_realm *realm; > > + lockdep_assert_held_write(&mdsc->snap_rwsem); This too since it boils down to calling __destroy_snap_realm(). > + > spin_lock(&mdsc->snap_empty_lock); > while (!list_empty(&mdsc->snap_empty)) { > realm = list_first_entry(&mdsc->snap_empty, > @@ -269,6 +281,8 @@ static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc, > { > struct ceph_snap_realm *parent; > > + lockdep_assert_held_write(&mdsc->snap_rwsem); And this since ceph_lookup_snap_realm() is called right away. > + > if (realm->parent_ino == parentino) > return 0; > > @@ -696,6 +710,8 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, > int err = -ENOMEM; > LIST_HEAD(dirty_realms); > > + lockdep_assert_held_write(&mdsc->snap_rwsem); Ditto. Thanks, Ilya ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] ceph: add some lockdep assertions around snaprealm handling 2021-06-21 20:05 ` Ilya Dryomov @ 2021-06-21 20:51 ` Jeff Layton 2021-06-21 21:27 ` Ilya Dryomov 0 siblings, 1 reply; 9+ messages in thread From: Jeff Layton @ 2021-06-21 20:51 UTC (permalink / raw) To: Ilya Dryomov; +Cc: Ceph Development On Mon, 2021-06-21 at 22:05 +0200, Ilya Dryomov wrote: > On Thu, Jun 3, 2021 at 6:52 PM Jeff Layton <jlayton@kernel.org> wrote: > > > > Turn some comments into lockdep asserts. > > > > Signed-off-by: Jeff Layton <jlayton@kernel.org> > > --- > > fs/ceph/snap.c | 16 ++++++++++++++++ > > 1 file changed, 16 insertions(+) > > > > diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c > > index 2a63fb37778b..bc6c33d485e6 100644 > > --- a/fs/ceph/snap.c > > +++ b/fs/ceph/snap.c > > @@ -65,6 +65,8 @@ > > void ceph_get_snap_realm(struct ceph_mds_client *mdsc, > > struct ceph_snap_realm *realm) > > { > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > + > > dout("get_realm %p %d -> %d\n", realm, > > atomic_read(&realm->nref), atomic_read(&realm->nref)+1); > > /* > > @@ -113,6 +115,8 @@ static struct ceph_snap_realm *ceph_create_snap_realm( > > { > > struct ceph_snap_realm *realm; > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > + > > realm = kzalloc(sizeof(*realm), GFP_NOFS); > > if (!realm) > > return ERR_PTR(-ENOMEM); > > @@ -143,6 +147,8 @@ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, > > struct rb_node *n = mdsc->snap_realms.rb_node; > > struct ceph_snap_realm *r; > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > + > > while (n) { > > r = rb_entry(n, struct ceph_snap_realm, node); > > if (ino < r->ino) > > @@ -176,6 +182,8 @@ static void __put_snap_realm(struct ceph_mds_client *mdsc, > > static void __destroy_snap_realm(struct ceph_mds_client *mdsc, > > struct ceph_snap_realm *realm) > > { > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > + > > dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); > > > > rb_erase(&realm->node, &mdsc->snap_realms); > > @@ -198,6 +206,8 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc, > > static void __put_snap_realm(struct ceph_mds_client *mdsc, > > struct ceph_snap_realm *realm) > > { > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > This one appears to be redundant since the only caller is > __destroy_snap_realm(). > > > + > > dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm, > > atomic_read(&realm->nref), atomic_read(&realm->nref)-1); > > if (atomic_dec_and_test(&realm->nref)) > > @@ -236,6 +246,8 @@ static void __cleanup_empty_realms(struct ceph_mds_client *mdsc) > > { > > struct ceph_snap_realm *realm; > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > This too since it boils down to calling __destroy_snap_realm(). > > > + > > spin_lock(&mdsc->snap_empty_lock); > > while (!list_empty(&mdsc->snap_empty)) { > > realm = list_first_entry(&mdsc->snap_empty, > > @@ -269,6 +281,8 @@ static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc, > > { > > struct ceph_snap_realm *parent; > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > And this since ceph_lookup_snap_realm() is called right away. > > > + > > if (realm->parent_ino == parentino) > > return 0; > > > > @@ -696,6 +710,8 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, > > int err = -ENOMEM; > > LIST_HEAD(dirty_realms); > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > Ditto. > > Thanks, > > Ilya Some of these calls may be redundant, but I'd still like to keep them. The locking in this code is a mess, and this is the most reliable way I've found to approach cleaning it up. These all compile out unless you're running with lockdep enabled anyway. -- Jeff Layton <jlayton@kernel.org> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] ceph: add some lockdep assertions around snaprealm handling 2021-06-21 20:51 ` Jeff Layton @ 2021-06-21 21:27 ` Ilya Dryomov 0 siblings, 0 replies; 9+ messages in thread From: Ilya Dryomov @ 2021-06-21 21:27 UTC (permalink / raw) To: Jeff Layton; +Cc: Ceph Development On Mon, Jun 21, 2021 at 10:51 PM Jeff Layton <jlayton@kernel.org> wrote: > > On Mon, 2021-06-21 at 22:05 +0200, Ilya Dryomov wrote: > > On Thu, Jun 3, 2021 at 6:52 PM Jeff Layton <jlayton@kernel.org> wrote: > > > > > > Turn some comments into lockdep asserts. > > > > > > Signed-off-by: Jeff Layton <jlayton@kernel.org> > > > --- > > > fs/ceph/snap.c | 16 ++++++++++++++++ > > > 1 file changed, 16 insertions(+) > > > > > > diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c > > > index 2a63fb37778b..bc6c33d485e6 100644 > > > --- a/fs/ceph/snap.c > > > +++ b/fs/ceph/snap.c > > > @@ -65,6 +65,8 @@ > > > void ceph_get_snap_realm(struct ceph_mds_client *mdsc, > > > struct ceph_snap_realm *realm) > > > { > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > + > > > dout("get_realm %p %d -> %d\n", realm, > > > atomic_read(&realm->nref), atomic_read(&realm->nref)+1); > > > /* > > > @@ -113,6 +115,8 @@ static struct ceph_snap_realm *ceph_create_snap_realm( > > > { > > > struct ceph_snap_realm *realm; > > > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > + > > > realm = kzalloc(sizeof(*realm), GFP_NOFS); > > > if (!realm) > > > return ERR_PTR(-ENOMEM); > > > @@ -143,6 +147,8 @@ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, > > > struct rb_node *n = mdsc->snap_realms.rb_node; > > > struct ceph_snap_realm *r; > > > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > + > > > while (n) { > > > r = rb_entry(n, struct ceph_snap_realm, node); > > > if (ino < r->ino) > > > @@ -176,6 +182,8 @@ static void __put_snap_realm(struct ceph_mds_client *mdsc, > > > static void __destroy_snap_realm(struct ceph_mds_client *mdsc, > > > struct ceph_snap_realm *realm) > > > { > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > + > > > dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); > > > > > > rb_erase(&realm->node, &mdsc->snap_realms); > > > @@ -198,6 +206,8 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc, > > > static void __put_snap_realm(struct ceph_mds_client *mdsc, > > > struct ceph_snap_realm *realm) > > > { > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > > This one appears to be redundant since the only caller is > > __destroy_snap_realm(). > > > > > + > > > dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm, > > > atomic_read(&realm->nref), atomic_read(&realm->nref)-1); > > > if (atomic_dec_and_test(&realm->nref)) > > > @@ -236,6 +246,8 @@ static void __cleanup_empty_realms(struct ceph_mds_client *mdsc) > > > { > > > struct ceph_snap_realm *realm; > > > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > > This too since it boils down to calling __destroy_snap_realm(). > > > > > + > > > spin_lock(&mdsc->snap_empty_lock); > > > while (!list_empty(&mdsc->snap_empty)) { > > > realm = list_first_entry(&mdsc->snap_empty, > > > @@ -269,6 +281,8 @@ static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc, > > > { > > > struct ceph_snap_realm *parent; > > > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > > And this since ceph_lookup_snap_realm() is called right away. > > > > > + > > > if (realm->parent_ino == parentino) > > > return 0; > > > > > > @@ -696,6 +710,8 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, > > > int err = -ENOMEM; > > > LIST_HEAD(dirty_realms); > > > > > > + lockdep_assert_held_write(&mdsc->snap_rwsem); > > > > Ditto. > > > > Thanks, > > > > Ilya > > Some of these calls may be redundant, but I'd still like to keep them. > > The locking in this code is a mess, and this is the most reliable way > I've found to approach cleaning it up. These all compile out unless > you're running with lockdep enabled anyway. Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Thanks, Ilya ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm 2021-06-03 16:52 [PATCH 0/3] ceph: locking fixes for snaprealm handling Jeff Layton 2021-06-03 16:52 ` [PATCH 1/3] ceph: add some lockdep assertions around " Jeff Layton @ 2021-06-03 16:52 ` Jeff Layton 2021-06-21 20:48 ` Ilya Dryomov 2021-06-03 16:52 ` [PATCH 3/3] ceph: must hold snap_rwsem when filling inode for async create Jeff Layton 2 siblings, 1 reply; 9+ messages in thread From: Jeff Layton @ 2021-06-03 16:52 UTC (permalink / raw) To: ceph-devel, idryomov They both say that the snap_rwsem must be held for write, but I don't see any real reason for it, and it's not currently always called that way. The lookup is just walking the rbtree, so holding it for read should be fine there. The "get" is bumping the refcount and (possibly) removing it from the empty list. I see no need to hold the snap_rwsem for write for that. Signed-off-by: Jeff Layton <jlayton@kernel.org> --- fs/ceph/snap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index bc6c33d485e6..f8cac2abab3f 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -60,12 +60,12 @@ /* * increase ref count for the realm * - * caller must hold snap_rwsem for write. + * caller must hold snap_rwsem. */ void ceph_get_snap_realm(struct ceph_mds_client *mdsc, struct ceph_snap_realm *realm) { - lockdep_assert_held_write(&mdsc->snap_rwsem); + lockdep_assert_held(&mdsc->snap_rwsem); dout("get_realm %p %d -> %d\n", realm, atomic_read(&realm->nref), atomic_read(&realm->nref)+1); @@ -139,7 +139,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm( /* * lookup the realm rooted at @ino. * - * caller must hold snap_rwsem for write. + * caller must hold snap_rwsem. */ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, u64 ino) @@ -147,7 +147,7 @@ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, struct rb_node *n = mdsc->snap_realms.rb_node; struct ceph_snap_realm *r; - lockdep_assert_held_write(&mdsc->snap_rwsem); + lockdep_assert_held(&mdsc->snap_rwsem); while (n) { r = rb_entry(n, struct ceph_snap_realm, node); -- 2.31.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm 2021-06-03 16:52 ` [PATCH 2/3] ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm Jeff Layton @ 2021-06-21 20:48 ` Ilya Dryomov 0 siblings, 0 replies; 9+ messages in thread From: Ilya Dryomov @ 2021-06-21 20:48 UTC (permalink / raw) To: Jeff Layton; +Cc: Ceph Development On Thu, Jun 3, 2021 at 6:52 PM Jeff Layton <jlayton@kernel.org> wrote: > > They both say that the snap_rwsem must be held for write, but I don't > see any real reason for it, and it's not currently always called that > way. > > The lookup is just walking the rbtree, so holding it for read should be > fine there. The "get" is bumping the refcount and (possibly) removing > it from the empty list. I see no need to hold the snap_rwsem for write > for that. > > Signed-off-by: Jeff Layton <jlayton@kernel.org> > --- > fs/ceph/snap.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c > index bc6c33d485e6..f8cac2abab3f 100644 > --- a/fs/ceph/snap.c > +++ b/fs/ceph/snap.c > @@ -60,12 +60,12 @@ > /* > * increase ref count for the realm > * > - * caller must hold snap_rwsem for write. > + * caller must hold snap_rwsem. > */ > void ceph_get_snap_realm(struct ceph_mds_client *mdsc, > struct ceph_snap_realm *realm) > { > - lockdep_assert_held_write(&mdsc->snap_rwsem); > + lockdep_assert_held(&mdsc->snap_rwsem); > > dout("get_realm %p %d -> %d\n", realm, > atomic_read(&realm->nref), atomic_read(&realm->nref)+1); > @@ -139,7 +139,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm( > /* > * lookup the realm rooted at @ino. > * > - * caller must hold snap_rwsem for write. > + * caller must hold snap_rwsem. > */ > static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, > u64 ino) > @@ -147,7 +147,7 @@ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc, > struct rb_node *n = mdsc->snap_realms.rb_node; > struct ceph_snap_realm *r; > > - lockdep_assert_held_write(&mdsc->snap_rwsem); > + lockdep_assert_held(&mdsc->snap_rwsem); > > while (n) { > r = rb_entry(n, struct ceph_snap_realm, node); > -- > 2.31.1 > Ah, since you are relaxing the requirement some of those lockdep asserts from the previous patch aren't actually redundant. This seems fine to me: lookup definitely doesn't need the write lock and allowing concurrent gets should be OK. The write lock made some sense back when get was an atomic_read followed by atomic_inc but not now. Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Thanks, Ilya ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] ceph: must hold snap_rwsem when filling inode for async create 2021-06-03 16:52 [PATCH 0/3] ceph: locking fixes for snaprealm handling Jeff Layton 2021-06-03 16:52 ` [PATCH 1/3] ceph: add some lockdep assertions around " Jeff Layton 2021-06-03 16:52 ` [PATCH 2/3] ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm Jeff Layton @ 2021-06-03 16:52 ` Jeff Layton 2021-06-21 19:45 ` Ilya Dryomov 2 siblings, 1 reply; 9+ messages in thread From: Jeff Layton @ 2021-06-03 16:52 UTC (permalink / raw) To: ceph-devel, idryomov; +Cc: stable ...and add a lockdep assertion for it to ceph_fill_inode(). Cc: stable@vger.kernel.org # v5.7+ Fixes: 9a8d03ca2e2c3 ("ceph: attempt to do async create when possible") Signed-off-by: Jeff Layton <jlayton@kernel.org> --- fs/ceph/file.c | 3 +++ fs/ceph/inode.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index a01ad342a91d..d3874c2df4b1 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -578,6 +578,7 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry, struct ceph_inode_info *ci = ceph_inode(dir); struct inode *inode; struct timespec64 now; + struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); struct ceph_vino vino = { .ino = req->r_deleg_ino, .snap = CEPH_NOSNAP }; @@ -615,8 +616,10 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry, ceph_file_layout_to_legacy(lo, &in.layout); + down_read(&mdsc->snap_rwsem); ret = ceph_fill_inode(inode, NULL, &iinfo, NULL, req->r_session, req->r_fmode, NULL); + up_read(&mdsc->snap_rwsem); if (ret) { dout("%s failed to fill inode: %d\n", __func__, ret); ceph_dir_clear_complete(dir); diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index e1c63adb196d..df0c8a724609 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -777,6 +777,8 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page, umode_t mode = le32_to_cpu(info->mode); dev_t rdev = le32_to_cpu(info->rdev); + lockdep_assert_held(&mdsc->snap_rwsem); + dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__, inode, ceph_vinop(inode), le64_to_cpu(info->version), ci->i_version); -- 2.31.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] ceph: must hold snap_rwsem when filling inode for async create 2021-06-03 16:52 ` [PATCH 3/3] ceph: must hold snap_rwsem when filling inode for async create Jeff Layton @ 2021-06-21 19:45 ` Ilya Dryomov 0 siblings, 0 replies; 9+ messages in thread From: Ilya Dryomov @ 2021-06-21 19:45 UTC (permalink / raw) To: Jeff Layton; +Cc: Ceph Development, stable On Thu, Jun 3, 2021 at 6:52 PM Jeff Layton <jlayton@kernel.org> wrote: > > ...and add a lockdep assertion for it to ceph_fill_inode(). > > Cc: stable@vger.kernel.org # v5.7+ > Fixes: 9a8d03ca2e2c3 ("ceph: attempt to do async create when possible") > Signed-off-by: Jeff Layton <jlayton@kernel.org> > --- > fs/ceph/file.c | 3 +++ > fs/ceph/inode.c | 2 ++ > 2 files changed, 5 insertions(+) > > diff --git a/fs/ceph/file.c b/fs/ceph/file.c > index a01ad342a91d..d3874c2df4b1 100644 > --- a/fs/ceph/file.c > +++ b/fs/ceph/file.c > @@ -578,6 +578,7 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry, > struct ceph_inode_info *ci = ceph_inode(dir); > struct inode *inode; > struct timespec64 now; > + struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); > struct ceph_vino vino = { .ino = req->r_deleg_ino, > .snap = CEPH_NOSNAP }; > > @@ -615,8 +616,10 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry, > > ceph_file_layout_to_legacy(lo, &in.layout); > > + down_read(&mdsc->snap_rwsem); > ret = ceph_fill_inode(inode, NULL, &iinfo, NULL, req->r_session, > req->r_fmode, NULL); > + up_read(&mdsc->snap_rwsem); > if (ret) { > dout("%s failed to fill inode: %d\n", __func__, ret); > ceph_dir_clear_complete(dir); > diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c > index e1c63adb196d..df0c8a724609 100644 > --- a/fs/ceph/inode.c > +++ b/fs/ceph/inode.c > @@ -777,6 +777,8 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page, > umode_t mode = le32_to_cpu(info->mode); > dev_t rdev = le32_to_cpu(info->rdev); > > + lockdep_assert_held(&mdsc->snap_rwsem); > + > dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__, > inode, ceph_vinop(inode), le64_to_cpu(info->version), > ci->i_version); > -- > 2.31.1 > Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Thanks, Ilya ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-06-21 21:27 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-06-03 16:52 [PATCH 0/3] ceph: locking fixes for snaprealm handling Jeff Layton 2021-06-03 16:52 ` [PATCH 1/3] ceph: add some lockdep assertions around " Jeff Layton 2021-06-21 20:05 ` Ilya Dryomov 2021-06-21 20:51 ` Jeff Layton 2021-06-21 21:27 ` Ilya Dryomov 2021-06-03 16:52 ` [PATCH 2/3] ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm Jeff Layton 2021-06-21 20:48 ` Ilya Dryomov 2021-06-03 16:52 ` [PATCH 3/3] ceph: must hold snap_rwsem when filling inode for async create Jeff Layton 2021-06-21 19:45 ` Ilya Dryomov
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.