fs: new API for handling inode->i_version
[linux-2.6-microblaze.git] / include / linux / iversion.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_IVERSION_H
3 #define _LINUX_IVERSION_H
4
5 #include <linux/fs.h>
6
7 /*
8  * The change attribute (i_version) is mandated by NFSv4 and is mostly for
9  * knfsd, but is also used for other purposes (e.g. IMA). The i_version must
10  * appear different to observers if there was a change to the inode's data or
11  * metadata since it was last queried.
12  *
13  * Observers see the i_version as a 64-bit number that never decreases. If it
14  * remains the same since it was last checked, then nothing has changed in the
15  * inode. If it's different then something has changed. Observers cannot infer
16  * anything about the nature or magnitude of the changes from the value, only
17  * that the inode has changed in some fashion.
18  *
19  * Not all filesystems properly implement the i_version counter. Subsystems that
20  * want to use i_version field on an inode should first check whether the
21  * filesystem sets the SB_I_VERSION flag (usually via the IS_I_VERSION macro).
22  *
23  * Those that set SB_I_VERSION will automatically have their i_version counter
24  * incremented on writes to normal files. If the SB_I_VERSION is not set, then
25  * the VFS will not touch it on writes, and the filesystem can use it how it
26  * wishes. Note that the filesystem is always responsible for updating the
27  * i_version on namespace changes in directories (mkdir, rmdir, unlink, etc.).
28  * We consider these sorts of filesystems to have a kernel-managed i_version.
29  *
30  * It may be impractical for filesystems to keep i_version updates atomic with
31  * respect to the changes that cause them.  They should, however, guarantee
32  * that i_version updates are never visible before the changes that caused
33  * them.  Also, i_version updates should never be delayed longer than it takes
34  * the original change to reach disk.
35  *
36  * Note that some filesystems (e.g. NFS and AFS) just use the field to store
37  * a server-provided value (for the most part). For that reason, those
38  * filesystems do not set SB_I_VERSION. These filesystems are considered to
39  * have a self-managed i_version.
40  */
41
42 /**
43  * inode_set_iversion_raw - set i_version to the specified raw value
44  * @inode: inode to set
45  * @new: new i_version value to set
46  *
47  * Set @inode's i_version field to @new. This function is for use by
48  * filesystems that self-manage the i_version.
49  *
50  * For example, the NFS client stores its NFSv4 change attribute in this way,
51  * and the AFS client stores the data_version from the server here.
52  */
53 static inline void
54 inode_set_iversion_raw(struct inode *inode, u64 new)
55 {
56         inode->i_version = new;
57 }
58
59 /**
60  * inode_set_iversion - set i_version to a particular value
61  * @inode: inode to set
62  * @new: new i_version value to set
63  *
64  * Set @inode's i_version field to @new. This function is for filesystems with
65  * a kernel-managed i_version.
66  *
67  * For now, this just does the same thing as the _raw variant.
68  */
69 static inline void
70 inode_set_iversion(struct inode *inode, u64 new)
71 {
72         inode_set_iversion_raw(inode, new);
73 }
74
75 /**
76  * inode_set_iversion_queried - set i_version to a particular value and set
77  *                              flag to indicate that it has been viewed
78  * @inode: inode to set
79  * @new: new i_version value to set
80  *
81  * When loading in an i_version value from a backing store, we typically don't
82  * know whether it was previously viewed before being stored or not. Thus, we
83  * must assume that it was, to ensure that any changes will result in the
84  * value changing.
85  *
86  * This function will set the inode's i_version, and possibly flag the value
87  * as if it has already been viewed at least once.
88  *
89  * For now, this just does what inode_set_iversion does.
90  */
91 static inline void
92 inode_set_iversion_queried(struct inode *inode, u64 new)
93 {
94         inode_set_iversion(inode, new);
95 }
96
97 /**
98  * inode_maybe_inc_iversion - increments i_version
99  * @inode: inode with the i_version that should be updated
100  * @force: increment the counter even if it's not necessary
101  *
102  * Every time the inode is modified, the i_version field must be seen to have
103  * changed by any observer.
104  *
105  * In this implementation, we always increment it after taking the i_lock to
106  * ensure that we don't race with other incrementors.
107  *
108  * Returns true if counter was bumped, and false if it wasn't.
109  */
110 static inline bool
111 inode_maybe_inc_iversion(struct inode *inode, bool force)
112 {
113         spin_lock(&inode->i_lock);
114         inode->i_version++;
115         spin_unlock(&inode->i_lock);
116         return true;
117 }
118
119 /**
120  * inode_inc_iversion - forcibly increment i_version
121  * @inode: inode that needs to be updated
122  *
123  * Forcbily increment the i_version field. This always results in a change to
124  * the observable value.
125  */
126 static inline void
127 inode_inc_iversion(struct inode *inode)
128 {
129         inode_maybe_inc_iversion(inode, true);
130 }
131
132 /**
133  * inode_iversion_need_inc - is the i_version in need of being incremented?
134  * @inode: inode to check
135  *
136  * Returns whether the inode->i_version counter needs incrementing on the next
137  * change.
138  *
139  * For now, we assume that it always does.
140  */
141 static inline bool
142 inode_iversion_need_inc(struct inode *inode)
143 {
144         return true;
145 }
146
147 /**
148  * inode_peek_iversion_raw - grab a "raw" iversion value
149  * @inode: inode from which i_version should be read
150  *
151  * Grab a "raw" inode->i_version value and return it. The i_version is not
152  * flagged or converted in any way. This is mostly used to access a self-managed
153  * i_version.
154  *
155  * With those filesystems, we want to treat the i_version as an entirely
156  * opaque value.
157  */
158 static inline u64
159 inode_peek_iversion_raw(const struct inode *inode)
160 {
161         return inode->i_version;
162 }
163
164 /**
165  * inode_inc_iversion_raw - forcibly increment raw i_version
166  * @inode: inode that needs to be updated
167  *
168  * Forcbily increment the raw i_version field. This always results in a change
169  * to the raw value.
170  *
171  * NFS will use the i_version field to store the value from the server. It
172  * mostly treats it as opaque, but in the case where it holds a write
173  * delegation, it must increment the value itself. This function does that.
174  */
175 static inline void
176 inode_inc_iversion_raw(struct inode *inode)
177 {
178         inode_inc_iversion(inode);
179 }
180
181 /**
182  * inode_peek_iversion - read i_version without flagging it to be incremented
183  * @inode: inode from which i_version should be read
184  *
185  * Read the inode i_version counter for an inode without registering it as a
186  * query.
187  *
188  * This is typically used by local filesystems that need to store an i_version
189  * on disk. In that situation, it's not necessary to flag it as having been
190  * viewed, as the result won't be used to gauge changes from that point.
191  */
192 static inline u64
193 inode_peek_iversion(const struct inode *inode)
194 {
195         return inode_peek_iversion_raw(inode);
196 }
197
198 /**
199  * inode_query_iversion - read i_version for later use
200  * @inode: inode from which i_version should be read
201  *
202  * Read the inode i_version counter. This should be used by callers that wish
203  * to store the returned i_version for later comparison. This will guarantee
204  * that a later query of the i_version will result in a different value if
205  * anything has changed.
206  *
207  * This implementation just does a peek.
208  */
209 static inline u64
210 inode_query_iversion(struct inode *inode)
211 {
212         return inode_peek_iversion(inode);
213 }
214
215 /**
216  * inode_cmp_iversion_raw - check whether the raw i_version counter has changed
217  * @inode: inode to check
218  * @old: old value to check against its i_version
219  *
220  * Compare the current raw i_version counter with a previous one. Returns 0 if
221  * they are the same or non-zero if they are different.
222  */
223 static inline s64
224 inode_cmp_iversion_raw(const struct inode *inode, u64 old)
225 {
226         return (s64)inode_peek_iversion_raw(inode) - (s64)old;
227 }
228
229 /**
230  * inode_cmp_iversion - check whether the i_version counter has changed
231  * @inode: inode to check
232  * @old: old value to check against its i_version
233  *
234  * Compare an i_version counter with a previous one. Returns 0 if they are
235  * the same or non-zero if they are different.
236  */
237 static inline s64
238 inode_cmp_iversion(const struct inode *inode, u64 old)
239 {
240         return (s64)inode_peek_iversion(inode) - (s64)old;
241 }
242 #endif