Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-or-later */
2 : /*
3 : * Copyright (C) 2018-2023 Oracle. All Rights Reserved.
4 : * Author: Darrick J. Wong <djwong@kernel.org>
5 : */
6 : #ifndef __XFS_SCRUB_XFILE_H__
7 : #define __XFS_SCRUB_XFILE_H__
8 :
9 : #ifdef CONFIG_XFS_IN_MEMORY_FILE
10 :
11 : struct xfile_page {
12 : struct page *page;
13 : void *fsdata;
14 : loff_t pos;
15 : };
16 :
17 : static inline bool xfile_page_cached(const struct xfile_page *xfpage)
18 : {
19 1613182280 : return xfpage->page != NULL;
20 : }
21 :
22 : static inline pgoff_t xfile_page_index(const struct xfile_page *xfpage)
23 : {
24 715608842 : return xfpage->page->index;
25 : }
26 :
27 : struct xfile_cache {
28 : struct xfile_page xfpage;
29 : void *kaddr;
30 : };
31 :
32 : #define XFILE_CACHE_ENTRIES (sizeof(struct xfs_buf_cache) / \
33 : sizeof(struct xfile_cache))
34 :
35 : struct xfile {
36 : struct file *file;
37 :
38 : union {
39 : struct xfs_buf_cache bcache;
40 : struct xfile_cache cached[XFILE_CACHE_ENTRIES];
41 : };
42 :
43 : /* XFILE_* flags */
44 : unsigned int flags;
45 : };
46 :
47 : /* Use the internal cache for faster access. */
48 : #define XFILE_INTERNAL_CACHE (1U << 0)
49 :
50 : void xfile_cache_enable(struct xfile *xf);
51 : void xfile_cache_disable(struct xfile *xf);
52 :
53 : int xfile_create(const char *description, loff_t isize, struct xfile **xfilep);
54 : void xfile_destroy(struct xfile *xf);
55 :
56 : ssize_t xfile_pread(struct xfile *xf, void *buf, size_t count, loff_t pos);
57 : ssize_t xfile_pwrite(struct xfile *xf, const void *buf, size_t count,
58 : loff_t pos);
59 :
60 : /*
61 : * Load an object. Since we're treating this file as "memory", any error or
62 : * short IO is treated as a failure to allocate memory.
63 : */
64 : static inline int
65 9260960422 : xfile_obj_load(struct xfile *xf, void *buf, size_t count, loff_t pos)
66 : {
67 9260960422 : ssize_t ret = xfile_pread(xf, buf, count, pos);
68 :
69 9261649253 : if (ret < 0 || ret != count)
70 0 : return -ENOMEM;
71 : return 0;
72 : }
73 :
74 : /*
75 : * Store an object. Since we're treating this file as "memory", any error or
76 : * short IO is treated as a failure to allocate memory.
77 : */
78 : static inline int
79 7844748752 : xfile_obj_store(struct xfile *xf, const void *buf, size_t count, loff_t pos)
80 : {
81 7844748752 : ssize_t ret = xfile_pwrite(xf, buf, count, pos);
82 :
83 7857139824 : if (ret < 0 || ret != count)
84 0 : return -ENOMEM;
85 : return 0;
86 : }
87 :
88 : void xfile_discard(struct xfile *xf, loff_t pos, u64 count);
89 : int xfile_prealloc(struct xfile *xf, loff_t pos, u64 count);
90 : loff_t xfile_seek_data(struct xfile *xf, loff_t pos);
91 :
92 : struct xfile_stat {
93 : loff_t size;
94 : unsigned long long bytes;
95 : };
96 :
97 : int xfile_stat(struct xfile *xf, struct xfile_stat *statbuf);
98 :
99 : int xfile_get_page(struct xfile *xf, loff_t offset, unsigned int len,
100 : struct xfile_page *xbuf);
101 : int xfile_put_page(struct xfile *xf, struct xfile_page *xbuf);
102 :
103 : int xfile_dump(struct xfile *xf);
104 :
105 : static inline loff_t xfile_size(struct xfile *xf)
106 : {
107 3341807782 : return i_size_read(file_inode(xf->file));
108 : }
109 :
110 71563230885 : static inline unsigned long long xfile_bytes(struct xfile *xf)
111 : {
112 71563230885 : struct xfile_stat xs;
113 71563230885 : int ret;
114 :
115 71563230885 : ret = xfile_stat(xf, &xs);
116 71512512301 : if (ret)
117 : return 0;
118 :
119 71512512301 : return xs.bytes;
120 : }
121 :
122 : /* file block (aka system page size) to basic block conversions. */
123 : typedef unsigned long long xfileoff_t;
124 : #define XFB_BLOCKSIZE (PAGE_SIZE)
125 : #define XFB_BSHIFT (PAGE_SHIFT)
126 : #define XFB_SHIFT (XFB_BSHIFT - BBSHIFT)
127 :
128 : static inline loff_t xfo_to_b(xfileoff_t xfoff)
129 : {
130 378888 : return xfoff << XFB_BSHIFT;
131 : }
132 :
133 : static inline xfileoff_t b_to_xfo(loff_t pos)
134 : {
135 : return (pos + (XFB_BLOCKSIZE - 1)) >> XFB_BSHIFT;
136 : }
137 :
138 : static inline xfileoff_t b_to_xfot(loff_t pos)
139 : {
140 : return pos >> XFB_BSHIFT;
141 : }
142 :
143 : static inline xfs_daddr_t xfo_to_daddr(xfileoff_t xfoff)
144 : {
145 3342559242 : return xfoff << XFB_SHIFT;
146 : }
147 :
148 : static inline xfileoff_t xfs_daddr_to_xfo(xfs_daddr_t bb)
149 : {
150 378888 : return (bb + (xfo_to_daddr(1) - 1)) >> XFB_SHIFT;
151 : }
152 :
153 : static inline xfileoff_t xfs_daddr_to_xfot(xfs_daddr_t bb)
154 : {
155 25 : return bb >> XFB_SHIFT;
156 : }
157 : #else
158 : static inline int
159 : xfile_obj_load(struct xfile *xf, void *buf, size_t count, loff_t offset)
160 : {
161 : return -EIO;
162 : }
163 :
164 : static inline int
165 : xfile_obj_store(struct xfile *xf, const void *buf, size_t count, loff_t offset)
166 : {
167 : return -EIO;
168 : }
169 :
170 : static inline loff_t xfile_size(struct xfile *xf)
171 : {
172 : return 0;
173 : }
174 : #endif /* CONFIG_XFS_IN_MEMORY_FILE */
175 :
176 : #endif /* __XFS_SCRUB_XFILE_H__ */
|