Skip to content

Commit fc22600

Browse files
Stefan Roeschkdave
authored andcommitted
btrfs: make prepare_pages nowait compatible
Add nowait parameter to the prepare_pages function. In case nowait is specified for an async buffered write request, do a nowait allocation or return -EAGAIN. Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Stefan Roesch <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 80f9d24 commit fc22600

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

fs/btrfs/file.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,26 +1339,54 @@ static int prepare_uptodate_page(struct inode *inode,
13391339
return 0;
13401340
}
13411341

1342+
static unsigned int get_prepare_fgp_flags(bool nowait)
1343+
{
1344+
unsigned int fgp_flags = FGP_LOCK | FGP_ACCESSED | FGP_CREAT;
1345+
1346+
if (nowait)
1347+
fgp_flags |= FGP_NOWAIT;
1348+
1349+
return fgp_flags;
1350+
}
1351+
1352+
static gfp_t get_prepare_gfp_flags(struct inode *inode, bool nowait)
1353+
{
1354+
gfp_t gfp;
1355+
1356+
gfp = btrfs_alloc_write_mask(inode->i_mapping);
1357+
if (nowait) {
1358+
gfp &= ~__GFP_DIRECT_RECLAIM;
1359+
gfp |= GFP_NOWAIT;
1360+
}
1361+
1362+
return gfp;
1363+
}
1364+
13421365
/*
13431366
* this just gets pages into the page cache and locks them down.
13441367
*/
13451368
static noinline int prepare_pages(struct inode *inode, struct page **pages,
13461369
size_t num_pages, loff_t pos,
1347-
size_t write_bytes, bool force_uptodate)
1370+
size_t write_bytes, bool force_uptodate,
1371+
bool nowait)
13481372
{
13491373
int i;
13501374
unsigned long index = pos >> PAGE_SHIFT;
1351-
gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
1375+
gfp_t mask = get_prepare_gfp_flags(inode, nowait);
1376+
unsigned int fgp_flags = get_prepare_fgp_flags(nowait);
13521377
int err = 0;
13531378
int faili;
13541379

13551380
for (i = 0; i < num_pages; i++) {
13561381
again:
1357-
pages[i] = find_or_create_page(inode->i_mapping, index + i,
1358-
mask | __GFP_WRITE);
1382+
pages[i] = pagecache_get_page(inode->i_mapping, index + i,
1383+
fgp_flags, mask | __GFP_WRITE);
13591384
if (!pages[i]) {
13601385
faili = i - 1;
1361-
err = -ENOMEM;
1386+
if (nowait)
1387+
err = -EAGAIN;
1388+
else
1389+
err = -ENOMEM;
13621390
goto fail;
13631391
}
13641392

@@ -1376,7 +1404,7 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
13761404
pos + write_bytes, false);
13771405
if (err) {
13781406
put_page(pages[i]);
1379-
if (err == -EAGAIN) {
1407+
if (!nowait && err == -EAGAIN) {
13801408
err = 0;
13811409
goto again;
13821410
}
@@ -1714,8 +1742,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
17141742
* contents of pages from loop to loop
17151743
*/
17161744
ret = prepare_pages(inode, pages, num_pages,
1717-
pos, write_bytes,
1718-
force_page_uptodate);
1745+
pos, write_bytes, force_page_uptodate, false);
17191746
if (ret) {
17201747
btrfs_delalloc_release_extents(BTRFS_I(inode),
17211748
reserve_bytes);

0 commit comments

Comments
 (0)