summaryrefslogtreecommitdiffstats
path: root/modules/spl/spl-kobj.c
blob: ce0625b9f19429a928723d396eeced72c1fcf1a5 (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
#include <sys/kobj.h>
#include "config.h"

void *rootdir = NULL;
EXPORT_SYMBOL(rootdir);

struct _buf *
kobj_open_file(const char *name)
{
	struct _buf *file;
	struct file *fp;

	fp = filp_open(name, O_RDONLY, 0644);
	if (IS_ERR(fp))
		return ((_buf_t *)-1UL);

	file = kmem_zalloc(sizeof(_buf_t), KM_SLEEP);
	file->fp = fp;

	return file;
} /* kobj_open_file() */
EXPORT_SYMBOL(kobj_open_file);

void
kobj_close_file(struct _buf *file)
{
        filp_close(file->fp, 0);
        kmem_free(file, sizeof(_buf_t));

	return;
} /* kobj_close_file() */
EXPORT_SYMBOL(kobj_close_file);

int
kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
{
	loff_t offset = off;
	mm_segment_t saved_fs;
	int rc;

	if (!file || !file->fp)
		return -EINVAL;

	if (!file->fp->f_op || !file->fp->f_op->read)
		return -ENOSYS;

	/* Writable user data segment must be briefly increased for this
	 * process so we can use the user space read call paths to write
	 * in to memory allocated by the kernel. */
	saved_fs = get_fs();
        set_fs(get_ds());
	rc = file->fp->f_op->read(file->fp, buf, size, &offset);
	set_fs(saved_fs);

	return rc;
} /* kobj_read_file() */
EXPORT_SYMBOL(kobj_read_file);

int
kobj_get_filesize(struct _buf *file, uint64_t *size)
{
        struct kstat stat;
	int rc;

	if (!file || !file->fp || !size)
		return -EINVAL;

        rc = vfs_getattr(file->fp->f_vfsmnt, file->fp->f_dentry, &stat);
	if (rc)
		return rc;

        *size = stat.size;
        return rc;
} /* kobj_get_filesize() */
EXPORT_SYMBOL(kobj_get_filesize);