Skip to content

Commit 54d9938

Browse files
Trond Myklebustamschuma-ntap
authored andcommitted
NFS: Convert nfs_write_begin/end to use folios
Add a helper nfs_folio_grab_cache_write_begin() that can call __filemap_get_folio() directly with the appropriate parameters. Since write_begin()/write_end() take struct page arguments, just pass the folio->page back for now. Signed-off-by: Trond Myklebust <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 4cbf769 commit 54d9938

File tree

1 file changed

+41
-34
lines changed

1 file changed

+41
-34
lines changed

fs/nfs/file.c

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -276,34 +276,44 @@ EXPORT_SYMBOL_GPL(nfs_file_fsync);
276276
* and that the new data won't completely replace the old data in
277277
* that range of the file.
278278
*/
279-
static bool nfs_full_page_write(struct page *page, loff_t pos, unsigned int len)
279+
static bool nfs_folio_is_full_write(struct folio *folio, loff_t pos,
280+
unsigned int len)
280281
{
281-
unsigned int pglen = nfs_page_length(page);
282-
unsigned int offset = pos & (PAGE_SIZE - 1);
282+
unsigned int pglen = nfs_folio_length(folio);
283+
unsigned int offset = offset_in_folio(folio, pos);
283284
unsigned int end = offset + len;
284285

285286
return !pglen || (end >= pglen && !offset);
286287
}
287288

288-
static bool nfs_want_read_modify_write(struct file *file, struct page *page,
289-
loff_t pos, unsigned int len)
289+
static bool nfs_want_read_modify_write(struct file *file, struct folio *folio,
290+
loff_t pos, unsigned int len)
290291
{
291292
/*
292293
* Up-to-date pages, those with ongoing or full-page write
293294
* don't need read/modify/write
294295
*/
295-
if (PageUptodate(page) || PagePrivate(page) ||
296-
nfs_full_page_write(page, pos, len))
296+
if (folio_test_uptodate(folio) || folio_test_private(folio) ||
297+
nfs_folio_is_full_write(folio, pos, len))
297298
return false;
298299

299-
if (pnfs_ld_read_whole_page(file->f_mapping->host))
300+
if (pnfs_ld_read_whole_page(file_inode(file)))
300301
return true;
301302
/* Open for reading too? */
302303
if (file->f_mode & FMODE_READ)
303304
return true;
304305
return false;
305306
}
306307

308+
static struct folio *
309+
nfs_folio_grab_cache_write_begin(struct address_space *mapping, pgoff_t index)
310+
{
311+
unsigned fgp_flags = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE;
312+
313+
return __filemap_get_folio(mapping, index, fgp_flags,
314+
mapping_gfp_mask(mapping));
315+
}
316+
307317
/*
308318
* This does the "real" work of the write. We must allocate and lock the
309319
* page to be sent back to the generic routine, which then copies the
@@ -313,47 +323,44 @@ static bool nfs_want_read_modify_write(struct file *file, struct page *page,
313323
* increment the page use counts until he is done with the page.
314324
*/
315325
static int nfs_write_begin(struct file *file, struct address_space *mapping,
316-
loff_t pos, unsigned len,
317-
struct page **pagep, void **fsdata)
326+
loff_t pos, unsigned len, struct page **pagep,
327+
void **fsdata)
318328
{
319-
int ret;
320-
pgoff_t index = pos >> PAGE_SHIFT;
321-
struct page *page;
322329
struct folio *folio;
323330
int once_thru = 0;
331+
int ret;
324332

325333
dfprintk(PAGECACHE, "NFS: write_begin(%pD2(%lu), %u@%lld)\n",
326334
file, mapping->host->i_ino, len, (long long) pos);
327335

328336
start:
329-
page = grab_cache_page_write_begin(mapping, index);
330-
if (!page)
337+
folio = nfs_folio_grab_cache_write_begin(mapping, pos >> PAGE_SHIFT);
338+
if (!folio)
331339
return -ENOMEM;
332-
*pagep = page;
333-
folio = page_folio(page);
340+
*pagep = &folio->page;
334341

335342
ret = nfs_flush_incompatible(file, folio);
336343
if (ret) {
337-
unlock_page(page);
338-
put_page(page);
344+
folio_unlock(folio);
345+
folio_put(folio);
339346
} else if (!once_thru &&
340-
nfs_want_read_modify_write(file, page, pos, len)) {
347+
nfs_want_read_modify_write(file, folio, pos, len)) {
341348
once_thru = 1;
342349
ret = nfs_read_folio(file, folio);
343-
put_page(page);
350+
folio_put(folio);
344351
if (!ret)
345352
goto start;
346353
}
347354
return ret;
348355
}
349356

350357
static int nfs_write_end(struct file *file, struct address_space *mapping,
351-
loff_t pos, unsigned len, unsigned copied,
352-
struct page *page, void *fsdata)
358+
loff_t pos, unsigned len, unsigned copied,
359+
struct page *page, void *fsdata)
353360
{
354-
unsigned offset = pos & (PAGE_SIZE - 1);
355361
struct nfs_open_context *ctx = nfs_file_open_context(file);
356362
struct folio *folio = page_folio(page);
363+
unsigned offset = offset_in_folio(folio, pos);
357364
int status;
358365

359366
dfprintk(PAGECACHE, "NFS: write_end(%pD2(%lu), %u@%lld)\n",
@@ -363,26 +370,26 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
363370
* Zero any uninitialised parts of the page, and then mark the page
364371
* as up to date if it turns out that we're extending the file.
365372
*/
366-
if (!PageUptodate(page)) {
367-
unsigned pglen = nfs_page_length(page);
373+
if (!folio_test_uptodate(folio)) {
374+
size_t fsize = folio_size(folio);
375+
unsigned pglen = nfs_folio_length(folio);
368376
unsigned end = offset + copied;
369377

370378
if (pglen == 0) {
371-
zero_user_segments(page, 0, offset,
372-
end, PAGE_SIZE);
373-
SetPageUptodate(page);
379+
folio_zero_segments(folio, 0, offset, end, fsize);
380+
folio_mark_uptodate(folio);
374381
} else if (end >= pglen) {
375-
zero_user_segment(page, end, PAGE_SIZE);
382+
folio_zero_segment(folio, end, fsize);
376383
if (offset == 0)
377-
SetPageUptodate(page);
384+
folio_mark_uptodate(folio);
378385
} else
379-
zero_user_segment(page, pglen, PAGE_SIZE);
386+
folio_zero_segment(folio, pglen, fsize);
380387
}
381388

382389
status = nfs_update_folio(file, folio, offset, copied);
383390

384-
unlock_page(page);
385-
put_page(page);
391+
folio_unlock(folio);
392+
folio_put(folio);
386393

387394
if (status < 0)
388395
return status;

0 commit comments

Comments
 (0)