Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/fs/afs/file.c
15109 views
1
/* AFS filesystem file handling
2
*
3
* Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#include <linux/kernel.h>
13
#include <linux/module.h>
14
#include <linux/init.h>
15
#include <linux/fs.h>
16
#include <linux/pagemap.h>
17
#include <linux/writeback.h>
18
#include <linux/gfp.h>
19
#include "internal.h"
20
21
static int afs_readpage(struct file *file, struct page *page);
22
static void afs_invalidatepage(struct page *page, unsigned long offset);
23
static int afs_releasepage(struct page *page, gfp_t gfp_flags);
24
static int afs_launder_page(struct page *page);
25
26
static int afs_readpages(struct file *filp, struct address_space *mapping,
27
struct list_head *pages, unsigned nr_pages);
28
29
const struct file_operations afs_file_operations = {
30
.open = afs_open,
31
.release = afs_release,
32
.llseek = generic_file_llseek,
33
.read = do_sync_read,
34
.write = do_sync_write,
35
.aio_read = generic_file_aio_read,
36
.aio_write = afs_file_write,
37
.mmap = generic_file_readonly_mmap,
38
.splice_read = generic_file_splice_read,
39
.fsync = afs_fsync,
40
.lock = afs_lock,
41
.flock = afs_flock,
42
};
43
44
const struct inode_operations afs_file_inode_operations = {
45
.getattr = afs_getattr,
46
.setattr = afs_setattr,
47
.permission = afs_permission,
48
};
49
50
const struct address_space_operations afs_fs_aops = {
51
.readpage = afs_readpage,
52
.readpages = afs_readpages,
53
.set_page_dirty = afs_set_page_dirty,
54
.launder_page = afs_launder_page,
55
.releasepage = afs_releasepage,
56
.invalidatepage = afs_invalidatepage,
57
.write_begin = afs_write_begin,
58
.write_end = afs_write_end,
59
.writepage = afs_writepage,
60
.writepages = afs_writepages,
61
};
62
63
/*
64
* open an AFS file or directory and attach a key to it
65
*/
66
int afs_open(struct inode *inode, struct file *file)
67
{
68
struct afs_vnode *vnode = AFS_FS_I(inode);
69
struct key *key;
70
int ret;
71
72
_enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
73
74
key = afs_request_key(vnode->volume->cell);
75
if (IS_ERR(key)) {
76
_leave(" = %ld [key]", PTR_ERR(key));
77
return PTR_ERR(key);
78
}
79
80
ret = afs_validate(vnode, key);
81
if (ret < 0) {
82
_leave(" = %d [val]", ret);
83
return ret;
84
}
85
86
file->private_data = key;
87
_leave(" = 0");
88
return 0;
89
}
90
91
/*
92
* release an AFS file or directory and discard its key
93
*/
94
int afs_release(struct inode *inode, struct file *file)
95
{
96
struct afs_vnode *vnode = AFS_FS_I(inode);
97
98
_enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
99
100
key_put(file->private_data);
101
_leave(" = 0");
102
return 0;
103
}
104
105
#ifdef CONFIG_AFS_FSCACHE
106
/*
107
* deal with notification that a page was read from the cache
108
*/
109
static void afs_file_readpage_read_complete(struct page *page,
110
void *data,
111
int error)
112
{
113
_enter("%p,%p,%d", page, data, error);
114
115
/* if the read completes with an error, we just unlock the page and let
116
* the VM reissue the readpage */
117
if (!error)
118
SetPageUptodate(page);
119
unlock_page(page);
120
}
121
#endif
122
123
/*
124
* read page from file, directory or symlink, given a key to use
125
*/
126
int afs_page_filler(void *data, struct page *page)
127
{
128
struct inode *inode = page->mapping->host;
129
struct afs_vnode *vnode = AFS_FS_I(inode);
130
struct key *key = data;
131
size_t len;
132
off_t offset;
133
int ret;
134
135
_enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index);
136
137
BUG_ON(!PageLocked(page));
138
139
ret = -ESTALE;
140
if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
141
goto error;
142
143
/* is it cached? */
144
#ifdef CONFIG_AFS_FSCACHE
145
ret = fscache_read_or_alloc_page(vnode->cache,
146
page,
147
afs_file_readpage_read_complete,
148
NULL,
149
GFP_KERNEL);
150
#else
151
ret = -ENOBUFS;
152
#endif
153
switch (ret) {
154
/* read BIO submitted (page in cache) */
155
case 0:
156
break;
157
158
/* page not yet cached */
159
case -ENODATA:
160
_debug("cache said ENODATA");
161
goto go_on;
162
163
/* page will not be cached */
164
case -ENOBUFS:
165
_debug("cache said ENOBUFS");
166
default:
167
go_on:
168
offset = page->index << PAGE_CACHE_SHIFT;
169
len = min_t(size_t, i_size_read(inode) - offset, PAGE_SIZE);
170
171
/* read the contents of the file from the server into the
172
* page */
173
ret = afs_vnode_fetch_data(vnode, key, offset, len, page);
174
if (ret < 0) {
175
if (ret == -ENOENT) {
176
_debug("got NOENT from server"
177
" - marking file deleted and stale");
178
set_bit(AFS_VNODE_DELETED, &vnode->flags);
179
ret = -ESTALE;
180
}
181
182
#ifdef CONFIG_AFS_FSCACHE
183
fscache_uncache_page(vnode->cache, page);
184
#endif
185
BUG_ON(PageFsCache(page));
186
goto error;
187
}
188
189
SetPageUptodate(page);
190
191
/* send the page to the cache */
192
#ifdef CONFIG_AFS_FSCACHE
193
if (PageFsCache(page) &&
194
fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
195
fscache_uncache_page(vnode->cache, page);
196
BUG_ON(PageFsCache(page));
197
}
198
#endif
199
unlock_page(page);
200
}
201
202
_leave(" = 0");
203
return 0;
204
205
error:
206
SetPageError(page);
207
unlock_page(page);
208
_leave(" = %d", ret);
209
return ret;
210
}
211
212
/*
213
* read page from file, directory or symlink, given a file to nominate the key
214
* to be used
215
*/
216
static int afs_readpage(struct file *file, struct page *page)
217
{
218
struct key *key;
219
int ret;
220
221
if (file) {
222
key = file->private_data;
223
ASSERT(key != NULL);
224
ret = afs_page_filler(key, page);
225
} else {
226
struct inode *inode = page->mapping->host;
227
key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell);
228
if (IS_ERR(key)) {
229
ret = PTR_ERR(key);
230
} else {
231
ret = afs_page_filler(key, page);
232
key_put(key);
233
}
234
}
235
return ret;
236
}
237
238
/*
239
* read a set of pages
240
*/
241
static int afs_readpages(struct file *file, struct address_space *mapping,
242
struct list_head *pages, unsigned nr_pages)
243
{
244
struct key *key = file->private_data;
245
struct afs_vnode *vnode;
246
int ret = 0;
247
248
_enter("{%d},{%lu},,%d",
249
key_serial(key), mapping->host->i_ino, nr_pages);
250
251
ASSERT(key != NULL);
252
253
vnode = AFS_FS_I(mapping->host);
254
if (vnode->flags & AFS_VNODE_DELETED) {
255
_leave(" = -ESTALE");
256
return -ESTALE;
257
}
258
259
/* attempt to read as many of the pages as possible */
260
#ifdef CONFIG_AFS_FSCACHE
261
ret = fscache_read_or_alloc_pages(vnode->cache,
262
mapping,
263
pages,
264
&nr_pages,
265
afs_file_readpage_read_complete,
266
NULL,
267
mapping_gfp_mask(mapping));
268
#else
269
ret = -ENOBUFS;
270
#endif
271
272
switch (ret) {
273
/* all pages are being read from the cache */
274
case 0:
275
BUG_ON(!list_empty(pages));
276
BUG_ON(nr_pages != 0);
277
_leave(" = 0 [reading all]");
278
return 0;
279
280
/* there were pages that couldn't be read from the cache */
281
case -ENODATA:
282
case -ENOBUFS:
283
break;
284
285
/* other error */
286
default:
287
_leave(" = %d", ret);
288
return ret;
289
}
290
291
/* load the missing pages from the network */
292
ret = read_cache_pages(mapping, pages, afs_page_filler, key);
293
294
_leave(" = %d [netting]", ret);
295
return ret;
296
}
297
298
/*
299
* write back a dirty page
300
*/
301
static int afs_launder_page(struct page *page)
302
{
303
_enter("{%lu}", page->index);
304
305
return 0;
306
}
307
308
/*
309
* invalidate part or all of a page
310
* - release a page and clean up its private data if offset is 0 (indicating
311
* the entire page)
312
*/
313
static void afs_invalidatepage(struct page *page, unsigned long offset)
314
{
315
struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
316
317
_enter("{%lu},%lu", page->index, offset);
318
319
BUG_ON(!PageLocked(page));
320
321
/* we clean up only if the entire page is being invalidated */
322
if (offset == 0) {
323
#ifdef CONFIG_AFS_FSCACHE
324
if (PageFsCache(page)) {
325
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
326
fscache_wait_on_page_write(vnode->cache, page);
327
fscache_uncache_page(vnode->cache, page);
328
}
329
#endif
330
331
if (PagePrivate(page)) {
332
if (wb && !PageWriteback(page)) {
333
set_page_private(page, 0);
334
afs_put_writeback(wb);
335
}
336
337
if (!page_private(page))
338
ClearPagePrivate(page);
339
}
340
}
341
342
_leave("");
343
}
344
345
/*
346
* release a page and clean up its private state if it's not busy
347
* - return true if the page can now be released, false if not
348
*/
349
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
350
{
351
struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
352
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
353
354
_enter("{{%x:%u}[%lu],%lx},%x",
355
vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
356
gfp_flags);
357
358
/* deny if page is being written to the cache and the caller hasn't
359
* elected to wait */
360
#ifdef CONFIG_AFS_FSCACHE
361
if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) {
362
_leave(" = F [cache busy]");
363
return 0;
364
}
365
#endif
366
367
if (PagePrivate(page)) {
368
if (wb) {
369
set_page_private(page, 0);
370
afs_put_writeback(wb);
371
}
372
ClearPagePrivate(page);
373
}
374
375
/* indicate that the page can be released */
376
_leave(" = T");
377
return 1;
378
}
379
380