On Thu, May 26, 2022 at 10:43:51PM -0700, Christoph Hellwig wrote: > > static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data, > > + size_t len, loff_t pos) > > { > > struct inode *inode = sb_dqopt(sb)->files[type]; > > + struct address_space *mapping = inode->i_mapping; > > size_t toread; > > + pgoff_t index; > > loff_t i_size = i_size_read(inode); > > > > + if (pos > i_size) > > return 0; > > + if (pos + len > i_size) > > + len = i_size - pos; > > toread = len; > > + index = pos / PAGE_SIZE; > > + > > while (toread > 0) { > > + struct folio *folio = read_mapping_folio(mapping, index, NULL); > > + size_t tocopy = PAGE_SIZE - offset_in_page(pos); > > + void *src; > > + > > + if (IS_ERR(folio)) > > + return PTR_ERR(folio); > > + > > + src = kmap_local_folio(folio, offset_in_folio(folio, pos)); > > + memcpy(data, src, tocopy); > > + kunmap_local(src); > > It would be great to have a memcpy_from_folio like the existing > memcpy_from_page for this. Yes, I agree. It could copy more than a single page like zero_user_segments() does. > > + folio_put(folio); > > > > toread -= tocopy; > > data += tocopy; > > + pos += tocopy; > > + index++; > > } > > return len; > > And this whole helper is generic now. It might be worth to move it > into fs/quota/dquot.c as generic_quota_read. I was thinking it was filemap_read_kernel(inode, pos, dst, len) but perhaps both of these things ...