On Sat, Apr 27, 2024 at 12:27:52AM +0530, Ritesh Harjani wrote: > Matthew Wilcox <willy@xxxxxxxxxxxxx> writes: > > @@ -79,6 +79,7 @@ static void iomap_set_range_uptodate(struct folio *folio, size_t off, > > if (ifs) { > > spin_lock_irqsave(&ifs->state_lock, flags); > > uptodate = ifs_set_range_uptodate(folio, ifs, off, len); > > + ifs->read_bytes_pending -= len; > > spin_unlock_irqrestore(&ifs->state_lock, flags); > > } > > iomap_set_range_uptodate() gets called from ->write_begin() and > ->write_end() too. So what we are saying is we are updating > the state of read_bytes_pending even though we are not in > ->read_folio() or ->readahead() call? Exactly. > > > > @@ -208,6 +209,8 @@ static struct iomap_folio_state *ifs_alloc(struct inode *inode, > > spin_lock_init(&ifs->state_lock); > > if (folio_test_uptodate(folio)) > > bitmap_set(ifs->state, 0, nr_blocks); > > + else > > + ifs->read_bytes_pending = folio_size(folio); > > We might not come till here during ->read_folio -> ifs_alloc(). Since we > might have a cached ifs which was allocated during write to this folio. > > But unless you are saying that during writes, we would have set > ifs->r_b_p to folio_size() and when the read call happens, we use > the same value of the cached ifs. > Ok, I see. I was mostly focusing on updating ifs->r_b_p value only when > the reads bytes are actually pending during ->read_folio() or > ->readahead() and not updating r_b_p during writes. I see why you might want to think that way ... but this way is much less complex, don't you think? ;-) > ...One small problem which I see with this approach is - we might have > some non-zero value in ifs->r_b_p when ifs_free() gets called and it > might give a warning of non-zero ifs->r_b_p, because we updated > ifs->r_b_p during writes to a non-zero value, but the reads > never happend. Then during a call to ->release_folio, it will complain > of a non-zero ifs->r_b_p. Yes, we'll have to remove that assertion. I don't think that's a problem, do you?