Skip to contentSkip to conversation

gfs2: simplify current_tail() via list_last_entry_or_null()

PATCH In review Jeff Liu 2 participants 4 messages Nov 15, 2013 – Nov 18, 2013

Subsystems (2)
lore
Share & tools
lore

Jeff Liu

author
#0 lore raw

PATCH 3/6 gfs2: simplify current_tail() via list_last_entry_or_null()

From: Jie Liu <[email protected]>

Simplify the code in current_tail() via list_last_entry_or_null().

---
 fs/gfs2/log.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)
fs/gfs2/log.c +3 -7
index 610613f..555f767 100644
@@ -441,13 +441,9 @@ static unsigned int current_tail(struct gfs2_sbd *sdp)
 
 	spin_lock(&sdp->sd_ail_lock);
 
-	if (list_empty(&sdp->sd_ail1_list)) {
-		tail = sdp->sd_log_head;
-	} else {
-		tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans,
-				tr_list);
-		tail = tr->tr_first;
-	}
+	tr = list_last_entry_or_null(&sdp->sd_ail1_list, struct gfs2_trans,
+				     tr_list);
+	tail = tr ? tr->tr_first : sdp->sd_log_head;
 
 	spin_unlock(&sdp->sd_ail_lock);
 
Signature · 1 line
1.8.3.2
#1 lore raw
Quoted 6 lines · Jeff Liu
fs/gfs2/log.c +0 -1
@@ -441,13 +441,9 @@ static unsigned int current_tail(struct gfs2_sbd *sdp)
 
 	spin_lock(&sdp->sd_ail_lock);
 
-	if (list_empty(&sdp->sd_ail1_list)) {

fs/gfs2/log.c static unsigned int current_tail(struct gfs2_sbd *sdp) · line 447

Quoted 10 lines
fs/gfs2/log.c +3 -6
-		tail = sdp->sd_log_head;
-	} else {
-		tr = list_entry(sdp->sd_ail1_list.prev, struct gfs2_trans,
-				tr_list);
-		tail = tr->tr_first;
-	}
+	tr = list_last_entry_or_null(&sdp->sd_ail1_list, struct gfs2_trans,
+				     tr_list);
+	tail = tr ? tr->tr_first : sdp->sd_log_head;
 

Personally I agree with Steven. At least in this case list_last_entry_or_null() doesn't really help to simplify the code.

But probably list_last_entry() makes sense in the "else" branch, athough this is minor.

Off-topic. Not sure this really makes sense, but I was thinking about

	list_get_first(pos, head, member)	\
		((pos) = list_first_entry(head, typeof(*pos), member))

and list_get_first() last of course. The obvious advantage is that compared to

	tr = list_last_entry(sdp->sd_ail1_list, struct gfs2_trans, tr_list);

above you do not need to type "struct gfs2_trans",

	list_get_last(tr, sdp->sd_ail1_list, tr_list);

looks a bit better.

Oleg.

#2 lore raw

introduce list_get_first/last (Was: [PATCH 3/6] gfs2: simplify current_tail() via list_last_entry_or_null())

Quoted 13 lines · Oleg Nesterov

But probably list_last_entry() makes sense in the "else" branch, athough this is minor.

Off-topic. Not sure this really makes sense, but I was thinking about

	list_get_first(pos, head, member)	\
		((pos) = list_first_entry(head, typeof(*pos), member))

and list_get_first() last of course. The obvious advantage is that compared to

Quoted 7 lines
	tr = list_last_entry(sdp->sd_ail1_list, struct gfs2_trans, tr_list);

above you do not need to type "struct gfs2_trans",

	list_get_last(tr, sdp->sd_ail1_list, tr_list);

looks a bit better.

And list.h can use it too.

So how about the patch below? I can't decide whether it cleanups or uglfies the code, I do not trust my taste ;) But to me it looks a bit better this way.

Oleg.
--

include/linux/list.h +10 -4
index ef95941..f52aba8 100644
@@ -372,6 +372,12 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_last_entry(ptr, type, member) \
 	list_entry((ptr)->prev, type, member)
 
+#define list_get_first(pos, head, member)	\
+	((pos) = list_first_entry(head, typeof(*(pos)), member))
+
+#define list_get_last(pos, head, member)	\
+	((pos) = list_last_entry(head, typeof(*(pos)), member))
+
 /**
  * list_first_entry_or_null - get the first element from a list
  * @ptr:	the list head to take the element from.
@@ -443,7 +449,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry(pos, head, member)				\
-	for (pos = list_first_entry(head, typeof(*pos), member);	\
+	for (list_get_first(pos, head, member);				\
 	     &pos->member != (head);					\
 	     pos = list_next_entry(pos, member))
 
@@ -454,7 +460,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry_reverse(pos, head, member)			\
-	for (pos = list_last_entry(head, typeof(*pos), member);		\
+	for (list_get_last(pos, head, member);				\
 	     &pos->member != (head); 					\
 	     pos = list_prev_entry(pos, member))
 
@@ -517,7 +523,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry_safe(pos, n, head, member)			\
-	for (pos = list_first_entry(head, typeof(*pos), member),	\
+	for (list_get_first(pos, head, member),				\
 		n = list_next_entry(pos, member);			\
 	     &pos->member != (head); 					\
 	     pos = n, n = list_next_entry(n, member))
@@ -564,7 +570,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * of list entry.
  */
 #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
-	for (pos = list_last_entry(head, typeof(*pos), member),		\
+	for (list_get_last(pos, head, member),				\
 		n = list_prev_entry(pos, member);			\
 	     &pos->member != (head); 					\
 	     pos = n, n = list_prev_entry(n, member))
author
#3 lore raw

Re: introduce list_get_first/last (Was: [PATCH 3/6] gfs2: simplify current_tail() via list_last_entry_or_null())

Hi Oleg,

Sorry for my late response!

Quoted 20 lines · Oleg Nesterov
Quoted 19 lines · Oleg Nesterov

But probably list_last_entry() makes sense in the "else" branch, athough this is minor.

Off-topic. Not sure this really makes sense, but I was thinking about

	list_get_first(pos, head, member)	\
		((pos) = list_first_entry(head, typeof(*pos), member))

and list_get_first() last of course. The obvious advantage is that compared to

	tr = list_last_entry(sdp->sd_ail1_list, struct gfs2_trans, tr_list);

above you do not need to type "struct gfs2_trans",

	list_get_last(tr, sdp->sd_ail1_list, tr_list);
Quoted 7 lines
Quoted 1 line

looks a bit better.

And list.h can use it too.

So how about the patch below? I can't decide whether it cleanups or uglfies the code, I do not trust my taste ;) But to me it looks a bit better this way.

I personally think this is better for GFS2 case if I understood correctly, and it can make the existing list helper a bit neat per my taste :)

The current list_first_entry() works fine consider a common pattern below:

while (!list_empty(ptr)) {
	struct dummy *p = list_first_entry(ptr, struct dummy, member);

	....
}

But I'm not sure if we can find out more external use cases can get benefits with list_get_first/last...

Thanks,
-Jeff

Quoted 62 lines

Oleg.
--

include/linux/list.h +10 -4
index ef95941..f52aba8 100644
@@ -372,6 +372,12 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_last_entry(ptr, type, member) \
 	list_entry((ptr)->prev, type, member)
 
+#define list_get_first(pos, head, member)	\
+	((pos) = list_first_entry(head, typeof(*(pos)), member))
+
+#define list_get_last(pos, head, member)	\
+	((pos) = list_last_entry(head, typeof(*(pos)), member))
+
 /**
  * list_first_entry_or_null - get the first element from a list
  * @ptr:	the list head to take the element from.
@@ -443,7 +449,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry(pos, head, member)				\
-	for (pos = list_first_entry(head, typeof(*pos), member);	\
+	for (list_get_first(pos, head, member);				\
 	     &pos->member != (head);					\
 	     pos = list_next_entry(pos, member))
 
@@ -454,7 +460,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry_reverse(pos, head, member)			\
-	for (pos = list_last_entry(head, typeof(*pos), member);		\
+	for (list_get_last(pos, head, member);				\
 	     &pos->member != (head); 					\
 	     pos = list_prev_entry(pos, member))
 
@@ -517,7 +523,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * @member:	the name of the list_struct within the struct.
  */
 #define list_for_each_entry_safe(pos, n, head, member)			\
-	for (pos = list_first_entry(head, typeof(*pos), member),	\
+	for (list_get_first(pos, head, member),				\
 		n = list_next_entry(pos, member);			\
 	     &pos->member != (head); 					\
 	     pos = n, n = list_next_entry(n, member))
@@ -564,7 +570,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * of list entry.
  */
 #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
-	for (pos = list_last_entry(head, typeof(*pos), member),		\
+	for (list_get_last(pos, head, member),				\
 		n = list_prev_entry(pos, member);			\
 	     &pos->member != (head); 					\
 	     pos = n, n = list_prev_entry(n, member))

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs