[Devel] [PATCH VZ7] seq_operations next callbacks cleanup

Vasily Averin vvs at virtuozzo.com
Thu Jan 16 11:42:14 MSK 2020


seq_operations next callback should move the iterator forward 
to the next position in the sequence.
Some VZ-specific filesystems can skip such increment,
and trigger incorrect file output.

 # q=;while read -r r;do echo "$((++q)) $r";done</proc/bc/resources

https://bugs.openvz.org/browse/OVZ-7158

Signed-off-by: Vasily Averin <vvs at virtuozzo.com>

-------------- next part --------------
diff --git a/drivers/net/venetdev.c b/drivers/net/venetdev.c
index 28d06bca1f86..c4cb15883002 100644
--- a/drivers/net/venetdev.c
+++ b/drivers/net/venetdev.c
@@ -842,6 +842,7 @@ static void *veip_seq_next(struct seq_file *m, void *v, loff_t *pos)
 	struct hlist_node *p;
 	int i;
 
+	(*pos)++;
 	if (v == SEQ_START_TOKEN)
 		goto find;
 
@@ -855,7 +856,6 @@ static void *veip_seq_next(struct seq_file *m, void *v, loff_t *pos)
 		if (p != NULL) {
 			m->private = (void *)(long)(i + 1);
 found:
-			(*pos)++;
 			return p;
 		}
 	}
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index ed1f63eef74c..66babd97732d 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -1112,6 +1112,7 @@ static void *ext4_es_seq_shrinker_info_start(struct seq_file *seq, loff_t *pos)
 static void *
 ext4_es_seq_shrinker_info_next(struct seq_file *seq, void *v, loff_t *pos)
 {
+	(*pos)++;
 	return NULL;
 }
 
diff --git a/kernel/bc/io_prio.c b/kernel/bc/io_prio.c
index 16f5024c90bd..31b4db717903 100644
--- a/kernel/bc/io_prio.c
+++ b/kernel/bc/io_prio.c
@@ -91,10 +91,10 @@ static void *bc_iostat_next(struct seq_file *f, void *v, loff_t *ppos)
 {
 	struct user_beancounter *ub = v;
 
-	list_for_each_entry_continue_rcu(ub, &ub_list_head, ub_list) {
-		(*ppos)++;
+	(*ppos)++;
+	list_for_each_entry_continue_rcu(ub, &ub_list_head, ub_list)
 		return ub;
-	}
+
 	return NULL;
 }
 
diff --git a/kernel/bc/proc.c b/kernel/bc/proc.c
index efcfdbc9ee22..70ec6ff5f216 100644
--- a/kernel/bc/proc.c
+++ b/kernel/bc/proc.c
@@ -242,6 +242,7 @@ static void *ub_next(struct seq_file *f, void *v, loff_t *ppos)
 	struct user_beancounter *ub, *ret = NULL;
 	struct user_beancounter *exec_ub;
 
+	(*ppos)++;
 	exec_ub = get_exec_ub();
 	ub = (struct user_beancounter *)v;
 	rcu_read_lock();
@@ -251,7 +252,6 @@ static void *ub_next(struct seq_file *f, void *v, loff_t *ppos)
 			continue;
 		if (!get_beancounter_rcu(ub))
 			continue;
-		(*ppos)++;
 		ret = ub;
 		break;
 	}
diff --git a/kernel/ve/vecalls.c b/kernel/ve/vecalls.c
index 5503bde290d2..6488fe8143f0 100644
--- a/kernel/ve/vecalls.c
+++ b/kernel/ve/vecalls.c
@@ -318,9 +318,10 @@ EXPORT_SYMBOL(ve_seq_start);
 
 void *ve_seq_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	if (!ve_is_super(get_exec_env()))
+	if (!ve_is_super(get_exec_env())) {
+		(*pos)++;
 		return NULL;
-	else
+	} else
 		return seq_list_next(v, &ve_list_head, pos);
 }
 EXPORT_SYMBOL(ve_seq_next);
diff --git a/kernel/ve/vznetstat/vznetstat.c b/kernel/ve/vznetstat/vznetstat.c
index 77309a34e166..e0ca8d2fb027 100644
--- a/kernel/ve/vznetstat/vznetstat.c
+++ b/kernel/ve/vznetstat/vznetstat.c
@@ -1033,10 +1033,10 @@ static void *stat_seq_next(struct seq_file *m, void *v, loff_t *pos)
 	struct venet_stat *ptr = (struct venet_stat *)v;
 	int hash;
 
+	(*pos)++;
 	if (!ve_is_super(get_exec_env()))
 		return NULL;
 	hash = stat_hash(ptr->veid);
-	(*pos)++;
 	return next_stat(&hash, ptr);
 }
 
diff --git a/kernel/ve/vzstat.c b/kernel/ve/vzstat.c
index 772e34e4c07a..e4a3348f0276 100644
--- a/kernel/ve/vzstat.c
+++ b/kernel/ve/vzstat.c
@@ -620,6 +620,7 @@ static void *empty_seq_start(struct seq_file *m, loff_t *pos)
 
 static void *empty_seq_next(struct seq_file *m, void *v, loff_t *pos)
 {
+	(*pos)++;
 	return NULL;
 }
 


More information about the Devel mailing list