diff --cc net/rds/info.c index 499b3774860e,17061f6ff74e..21b32eb16559 --- a/net/rds/info.c +++ b/net/rds/info.c @@@ -239,16 -230,13 +239,16 @@@ call_func ret = lens.each; } - if (put_user(len, optlen)) - ret = -EFAULT; + opt->optlen = len; out: - if (pages) + /* + * iov_iter_extract_pages() pins only user-backed (ubuf) iters; + * iov_iter_extract_will_pin() reports whether an unpin is owed here. + */ + if (pages && iov_iter_extract_will_pin(&opt->iter_out)) - unpin_user_pages(pages, nr_pages); + unpin_user_pages_dirty_lock(pages, nr_pages, true); - kfree(pages); + kvfree(pages); return ret; }