blob: 68baf55c47a43a181afa83db6087afe99c5a97b2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
// SPDX-License-Identifier: GPL-2.0-only
/* Miscellaneous routines.
*
* Copyright (C) 2023 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#include <linux/swap.h>
#include "internal.h"
/**
* netfs_dirty_folio - Mark folio dirty and pin a cache object for writeback
* @mapping: The mapping the folio belongs to.
* @folio: The folio being dirtied.
*
* Set the dirty flag on a folio and pin an in-use cache object in memory so
* that writeback can later write to it. This is intended to be called from
* the filesystem's ->dirty_folio() method.
*
* Return: true if the dirty flag was set on the folio, false otherwise.
*/
bool netfs_dirty_folio(struct address_space *mapping, struct folio *folio)
{
struct inode *inode = mapping->host;
struct netfs_inode *ictx = netfs_inode(inode);
struct fscache_cookie *cookie = netfs_i_cookie(ictx);
bool need_use = false;
_enter("");
if (!filemap_dirty_folio(mapping, folio))
return false;
if (!fscache_cookie_valid(cookie))
return true;
if (!(inode->i_state & I_PINNING_NETFS_WB)) {
spin_lock(&inode->i_lock);
if (!(inode->i_state & I_PINNING_NETFS_WB)) {
inode->i_state |= I_PINNING_NETFS_WB;
need_use = true;
}
spin_unlock(&inode->i_lock);
if (need_use)
fscache_use_cookie(cookie, true);
}
return true;
}
EXPORT_SYMBOL(netfs_dirty_folio);
/**
* netfs_unpin_writeback - Unpin writeback resources
* @inode: The inode on which the cookie resides
* @wbc: The writeback control
*
* Unpin the writeback resources pinned by netfs_dirty_folio(). This is
* intended to be called as/by the netfs's ->write_inode() method.
*/
int netfs_unpin_writeback(struct inode *inode, struct writeback_control *wbc)
{
struct fscache_cookie *cookie = netfs_i_cookie(netfs_inode(inode));
if (wbc->unpinned_netfs_wb)
fscache_unuse_cookie(cookie, NULL, NULL);
return 0;
}
EXPORT_SYMBOL(netfs_unpin_writeback);
/**
* netfs_clear_inode_writeback - Clear writeback resources pinned by an inode
* @inode: The inode to clean up
* @aux: Auxiliary data to apply to the inode
*
* Clear any writeback resources held by an inode when the inode is evicted.
* This must be called before clear_inode() is called.
*/
void netfs_clear_inode_writeback(struct inode *inode, const void *aux)
{
struct fscache_cookie *cookie = netfs_i_cookie(netfs_inode(inode));
if (inode->i_state & I_PINNING_NETFS_WB) {
loff_t i_size = i_size_read(inode);
fscache_unuse_cookie(cookie, aux, &i_size);
}
}
EXPORT_SYMBOL(netfs_clear_inode_writeback);
|