]> git.proxmox.com Git - mirror_spl-debian.git/blame - modules/spl/spl-vnode.c
Add the initial vestigates of vnode support
[mirror_spl-debian.git] / modules / spl / spl-vnode.c
CommitLineData
0b3cf046 1#include <sys/sysmacros.h>
2#include "config.h"
3
4/*
5 * XXX: currently borrrowed from libsolcompat until this
6 * can be adapted to the linux kernel interfaces.
7 */
8#if 0
9/*
10 * =========================================================================
11 * vnode operations
12 * =========================================================================
13 */
14/*
15 * Note: for the xxxat() versions of these functions, we assume that the
16 * starting vp is always rootdir (which is true for spa_directory.c, the only
17 * ZFS consumer of these interfaces). We assert this is true, and then emulate
18 * them by adding '/' in front of the path.
19 */
20
21/*ARGSUSED*/
22int
23vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
24{
25 int fd;
26 vnode_t *vp;
27 int old_umask;
28 char realpath[MAXPATHLEN];
29 struct stat64 st;
30
31 /*
32 * If we're accessing a real disk from userland, we need to use
33 * the character interface to avoid caching. This is particularly
34 * important if we're trying to look at a real in-kernel storage
35 * pool from userland, e.g. via zdb, because otherwise we won't
36 * see the changes occurring under the segmap cache.
37 * On the other hand, the stupid character device returns zero
38 * for its size. So -- gag -- we open the block device to get
39 * its size, and remember it for subsequent VOP_GETATTR().
40 */
41#if defined(__sun__) || defined(__sun)
42 if (strncmp(path, "/dev/", 5) == 0) {
43#else
44 if (0) {
45#endif
46 char *dsk;
47 fd = open64(path, O_RDONLY);
48 if (fd == -1)
49 return (errno);
50 if (fstat64(fd, &st) == -1) {
51 close(fd);
52 return (errno);
53 }
54 close(fd);
55 (void) sprintf(realpath, "%s", path);
56 dsk = strstr(path, "/dsk/");
57 if (dsk != NULL)
58 (void) sprintf(realpath + (dsk - path) + 1, "r%s",
59 dsk + 1);
60 } else {
61 (void) sprintf(realpath, "%s", path);
62 if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
63 return (errno);
64 }
65
66#ifdef __linux__
67 if (!(flags & FCREAT) && S_ISBLK(st.st_mode)) {
68 flags |= O_DIRECT;
69 if (flags & FWRITE)
70 flags |= O_EXCL;
71 }
72#endif
73
74 if (flags & FCREAT)
75 old_umask = umask(0);
76
77 /*
78 * The construct 'flags - FREAD' conveniently maps combinations of
79 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
80 */
81 fd = open64(realpath, flags - FREAD, mode);
82
83 if (flags & FCREAT)
84 (void) umask(old_umask);
85
86 if (fd == -1)
87 return (errno);
88
89 if (fstat64(fd, &st) == -1) {
90 close(fd);
91 return (errno);
92 }
93
94 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
95
96 *vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
97
98 vp->v_fd = fd;
99 vp->v_size = st.st_size;
100 vp->v_mode = st.st_mode;
101 vp->v_path = spa_strdup(path);
102
103 return (0);
104}
105
106/*ARGSUSED*/
107int
108vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
109 int x3, vnode_t *startvp, int fd)
110{
111 char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
112 int ret;
113
114 ASSERT(startvp == rootdir);
115 (void) sprintf(realpath, "/%s", path);
116
117 /* fd ignored for now, need if want to simulate nbmand support */
118 ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
119
120 umem_free(realpath, strlen(path) + 2);
121
122 return (ret);
123}
124
125/*ARGSUSED*/
126int
127vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
128 int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
129{
130 ssize_t iolen, split;
131
132 if (uio == UIO_READ) {
133 iolen = pread64(vp->v_fd, addr, len, offset);
134 } else {
135 /*
136 * To simulate partial disk writes, we split writes into two
137 * system calls so that the process can be killed in between.
138 */
139#ifdef ZFS_DEBUG
140 if (!S_ISBLK(vp->v_mode) && !S_ISCHR(vp->v_mode)) {
141 split = (len > 0 ? rand() % len : 0);
142 iolen = pwrite64(vp->v_fd, addr, split, offset);
143 iolen += pwrite64(vp->v_fd, (char *)addr + split,
144 len - split, offset + split);
145 } else
146 iolen = pwrite64(vp->v_fd, addr, len, offset);
147#else
148 iolen = pwrite64(vp->v_fd, addr, len, offset);
149#endif
150 }
151
152 if (iolen < 0)
153 return (errno);
154 if (residp)
155 *residp = len - iolen;
156 else if (iolen != len)
157 return (EIO);
158 return (0);
159}
160
161void
162vn_close(vnode_t *vp)
163{
164 close(vp->v_fd);
165 spa_strfree(vp->v_path);
166 umem_free(vp, sizeof (vnode_t));
167}
168#endif