On 07/07/2014 11:00 AM, Naoya Horiguchi wrote:
quoted hunk ↗ jump to hunk
+.SH RETURN VALUE
+On success,
+.BR fincore ()
+returns 0.
+On error, \-1 is returned, and
+.I errno
+is set appropriately.
Is this accurate? From reading the syscall itself, it looked like it
did this:
quoted hunk ↗ jump to hunk
+ * Return value is the number of pages whose data is stored in fc->buffer.
+ */
+static long do_fincore(struct fincore_control *fc, int nr_pages)
and:
+SYSCALL_DEFINE6(fincore, int, fd, loff_t, start, long, nr_pages,
...
quoted hunk ↗ jump to hunk
+ while (fc.nr_pages > 0) {
+ memset(fc.buffer, 0, fc.buffer_size);
+ ret = do_fincore(&fc, min(step, fc.nr_pages));
+ /* Reached the end of the file */
+ if (ret == 0)
+ break;
+ if (ret < 0)
+ break;
...
+ }
...
+ return ret;
+}
Which seems that for a given loop of do_fincore(), you might end up
returning the result of that *single* iteration of do_fincore() instead
of the aggregate of the entire syscall.
So, it can return <0 on failure, 0 on success, or also an essentially
random >0 number on success too.
Why not just use the return value for something useful instead of
hacking in the extras->nr_entries stuff? Oh, and what if that
+ if (extra)
+ __put_user(nr, &extra->nr_entries);
fails? It seems like we might silently forget to tell userspace how
many entries we filled.