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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2022 Oracle. All Rights Reserved.
* Author: Darrick J. Wong <djwong@kernel.org>
*/
#ifndef __XFS_SCRUB_XFILE_H__
#define __XFS_SCRUB_XFILE_H__
#ifdef CONFIG_XFS_IN_MEMORY_FILE
struct xfile {
struct file *file;
};
int xfile_create(struct xfs_mount *mp, const char *description, loff_t isize,
struct xfile **xfilep);
void xfile_destroy(struct xfile *xf);
ssize_t xfile_pread(struct xfile *xf, void *buf, size_t count, loff_t pos);
ssize_t xfile_pwrite(struct xfile *xf, const void *buf, size_t count,
loff_t pos);
/*
* Load an object. Since we're treating this file as "memory", any error or
* short IO is treated as a failure to allocate memory.
*/
static inline int
xfile_obj_load(struct xfile *xf, void *buf, size_t count, loff_t pos)
{
ssize_t ret = xfile_pread(xf, buf, count, pos);
if (ret < 0 || ret != count)
return -ENOMEM;
return 0;
}
/*
* Store an object. Since we're treating this file as "memory", any error or
* short IO is treated as a failure to allocate memory.
*/
static inline int
xfile_obj_store(struct xfile *xf, const void *buf, size_t count, loff_t pos)
{
ssize_t ret = xfile_pwrite(xf, buf, count, pos);
if (ret < 0 || ret != count)
return -ENOMEM;
return 0;
}
void xfile_discard(struct xfile *xf, loff_t pos, u64 count);
int xfile_prealloc(struct xfile *xf, loff_t pos, u64 count);
loff_t xfile_seek_data(struct xfile *xf, loff_t pos);
struct xfile_stat {
loff_t size;
unsigned long long bytes;
};
int xfile_stat(struct xfile *xf, struct xfile_stat *statbuf);
int xfile_obj_get_page(struct xfile *xf, loff_t offset, unsigned int len,
struct page **pagep, void **fsdatap);
int xfile_obj_put_page(struct xfile *xf, loff_t offset, unsigned int len,
struct page *page, void *fsdata);
int xfile_dump(struct xfile *xf);
static inline loff_t xfile_size(struct xfile *xf)
{
return i_size_read(file_inode(xf->file));
}
/* file block (aka system page size) to basic block conversions. */
typedef unsigned long long xfileoff_t;
#define XFB_BLOCKSIZE (PAGE_SIZE)
#define XFB_BSHIFT (PAGE_SHIFT)
#define XFB_SHIFT (XFB_BSHIFT - BBSHIFT)
static inline loff_t xfo_to_b(xfileoff_t xfoff)
{
return xfoff << XFB_BSHIFT;
}
static inline xfileoff_t b_to_xfo(loff_t pos)
{
return (pos + (XFB_BLOCKSIZE - 1)) >> XFB_BSHIFT;
}
static inline xfileoff_t b_to_xfot(loff_t pos)
{
return pos >> XFB_BSHIFT;
}
static inline xfs_daddr_t xfo_to_daddr(xfileoff_t xfoff)
{
return xfoff << XFB_SHIFT;
}
static inline xfileoff_t xfs_daddr_to_xfo(xfs_daddr_t bb)
{
return (bb + (xfo_to_daddr(1) - 1)) >> XFB_SHIFT;
}
static inline xfileoff_t xfs_daddr_to_xfot(xfs_daddr_t bb)
{
return bb >> XFB_SHIFT;
}
#else
static inline int
xfile_obj_load(struct xfile *xf, void *buf, size_t count, loff_t offset)
{
return -EIO;
}
static inline int
xfile_obj_store(struct xfile *xf, const void *buf, size_t count, loff_t offset)
{
return -EIO;
}
static inline loff_t xfile_size(struct xfile *xf)
{
return 0;
}
#endif /* CONFIG_XFS_IN_MEMORY_FILE */
#endif /* __XFS_SCRUB_XFILE_H__ */
|