summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/xfile.h
blob: d9a09d71553b597cf14199c9c2de142c4dd417bc (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
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
/* 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;
}

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__ */