1 #include "splat-internal.h"
2 #include <linux/rcupdate.h>
4 #define SPLAT_SUBSYSTEM_VNODE 0x0900
5 #define SPLAT_VNODE_NAME "vnode"
6 #define SPLAT_VNODE_DESC "Kernel Vnode Tests"
8 #define SPLAT_VNODE_TEST1_ID 0x0901
9 #define SPLAT_VNODE_TEST1_NAME "vn_open"
10 #define SPLAT_VNODE_TEST1_DESC "Vn_open Test"
12 #define SPLAT_VNODE_TEST2_ID 0x0902
13 #define SPLAT_VNODE_TEST2_NAME "vn_openat"
14 #define SPLAT_VNODE_TEST2_DESC "Vn_openat Test"
16 #define SPLAT_VNODE_TEST3_ID 0x0903
17 #define SPLAT_VNODE_TEST3_NAME "vn_rdwr"
18 #define SPLAT_VNODE_TEST3_DESC "Vn_rdwrt Test"
20 #define SPLAT_VNODE_TEST4_ID 0x0904
21 #define SPLAT_VNODE_TEST4_NAME "vn_rename"
22 #define SPLAT_VNODE_TEST4_DESC "Vn_rename Test"
24 #define SPLAT_VNODE_TEST5_ID 0x0905
25 #define SPLAT_VNODE_TEST5_NAME "vn_getattr"
26 #define SPLAT_VNODE_TEST5_DESC "Vn_getattr Test"
28 #define SPLAT_VNODE_TEST6_ID 0x0906
29 #define SPLAT_VNODE_TEST6_NAME "vn_sync"
30 #define SPLAT_VNODE_TEST6_DESC "Vn_sync Test"
32 #define SPLAT_VNODE_TEST7_ID 0x0907
33 #define SPLAT_VNODE_TEST7_NAME "getf"
34 #define SPLAT_VNODE_TEST7_DESC "getf/releasef Test"
36 #define SPLAT_VNODE_TEST_FILE "/etc/fstab"
37 #define SPLAT_VNODE_TEST_FILE_AT "etc/fstab"
38 #define SPLAT_VNODE_TEST_FILE_RW "/tmp/spl.vnode.tmp"
39 #define SPLAT_VNODE_TEST_FILE_RW1 "/tmp/spl.vnode.tmp.1"
40 #define SPLAT_VNODE_TEST_FILE_RW2 "/tmp/spl.vnode.tmp.2"
43 splat_vnode_test1(struct file
*file
, void *arg
)
48 if ((rc
= vn_open(SPLAT_VNODE_TEST_FILE
, UIO_SYSSPACE
,
49 FREAD
, 0644, &vp
, 0, 0))) {
50 splat_vprint(file
, SPLAT_VNODE_TEST1_NAME
,
51 "Failed to vn_open test file: %s (%d)\n",
52 SPLAT_VNODE_TEST_FILE
, rc
);
56 rc
= VOP_CLOSE(vp
, 0, 0, 0, 0, 0);
60 splat_vprint(file
, SPLAT_VNODE_TEST1_NAME
,
61 "Failed to vn_close test file: %s (%d)\n",
62 SPLAT_VNODE_TEST_FILE
, rc
);
66 splat_vprint(file
, SPLAT_VNODE_TEST1_NAME
, "Successfully vn_open'ed "
67 "and vn_closed test file: %s\n", SPLAT_VNODE_TEST_FILE
);
70 } /* splat_vnode_test1() */
73 splat_vnode_test2(struct file
*file
, void *arg
)
78 if ((rc
= vn_openat(SPLAT_VNODE_TEST_FILE_AT
, UIO_SYSSPACE
,
79 FREAD
, 0644, &vp
, 0, 0, rootdir
, 0))) {
80 splat_vprint(file
, SPLAT_VNODE_TEST2_NAME
,
81 "Failed to vn_openat test file: %s (%d)\n",
82 SPLAT_VNODE_TEST_FILE
, rc
);
86 rc
= VOP_CLOSE(vp
, 0, 0, 0, 0, 0);
90 splat_vprint(file
, SPLAT_VNODE_TEST2_NAME
,
91 "Failed to vn_close test file: %s (%d)\n",
92 SPLAT_VNODE_TEST_FILE
, rc
);
96 splat_vprint(file
, SPLAT_VNODE_TEST2_NAME
, "Successfully vn_openat'ed "
97 "and vn_closed test file: %s\n", SPLAT_VNODE_TEST_FILE
);
100 } /* splat_vnode_test2() */
103 splat_vnode_test3(struct file
*file
, void *arg
)
106 char buf1
[32] = "SPL VNode Interface Test File\n";
110 if ((rc
= vn_open(SPLAT_VNODE_TEST_FILE_RW
, UIO_SYSSPACE
,
111 FWRITE
| FREAD
| FCREAT
| FEXCL
,
113 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
,
114 "Failed to vn_open test file: %s (%d)\n",
115 SPLAT_VNODE_TEST_FILE_RW
, rc
);
119 rc
= vn_rdwr(UIO_WRITE
, vp
, buf1
, strlen(buf1
), 0,
120 UIO_SYSSPACE
, 0, RLIM64_INFINITY
, 0, NULL
);
122 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
,
123 "Failed vn_rdwr write of test file: %s (%d)\n",
124 SPLAT_VNODE_TEST_FILE_RW
, rc
);
128 rc
= vn_rdwr(UIO_READ
, vp
, buf2
, strlen(buf1
), 0,
129 UIO_SYSSPACE
, 0, RLIM64_INFINITY
, 0, NULL
);
131 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
,
132 "Failed vn_rdwr read of test file: %s (%d)\n",
133 SPLAT_VNODE_TEST_FILE_RW
, rc
);
137 if (strncmp(buf1
, buf2
, strlen(buf1
))) {
139 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
,
140 "Failed strncmp data written does not match "
141 "data read\nWrote: %sRead: %s\n", buf1
, buf2
);
146 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
, "Wrote: %s", buf1
);
147 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
, "Read: %s", buf2
);
148 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
, "Successfully wrote and "
149 "read expected data pattern to test file: %s\n",
150 SPLAT_VNODE_TEST_FILE_RW
);
153 VOP_CLOSE(vp
, 0, 0, 0, 0, 0);
155 vn_remove(SPLAT_VNODE_TEST_FILE_RW
, UIO_SYSSPACE
, RMFILE
);
158 } /* splat_vnode_test3() */
161 splat_vnode_test4(struct file
*file
, void *arg
)
164 char buf1
[32] = "SPL VNode Interface Test File\n";
168 if ((rc
= vn_open(SPLAT_VNODE_TEST_FILE_RW1
, UIO_SYSSPACE
,
169 FWRITE
| FREAD
| FCREAT
| FEXCL
, 0644, &vp
, 0, 0))) {
170 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
,
171 "Failed to vn_open test file: %s (%d)\n",
172 SPLAT_VNODE_TEST_FILE_RW1
, rc
);
176 rc
= vn_rdwr(UIO_WRITE
, vp
, buf1
, strlen(buf1
), 0,
177 UIO_SYSSPACE
, 0, RLIM64_INFINITY
, 0, NULL
);
179 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
,
180 "Failed vn_rdwr write of test file: %s (%d)\n",
181 SPLAT_VNODE_TEST_FILE_RW1
, rc
);
185 VOP_CLOSE(vp
, 0, 0, 0, 0, 0);
188 rc
= vn_rename(SPLAT_VNODE_TEST_FILE_RW1
,SPLAT_VNODE_TEST_FILE_RW2
,0);
190 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
, "Failed vn_rename "
192 SPLAT_VNODE_TEST_FILE_RW1
,
193 SPLAT_VNODE_TEST_FILE_RW2
, rc
);
197 if ((rc
= vn_open(SPLAT_VNODE_TEST_FILE_RW2
, UIO_SYSSPACE
,
198 FREAD
| FEXCL
, 0644, &vp
, 0, 0))) {
199 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
,
200 "Failed to vn_open test file: %s (%d)\n",
201 SPLAT_VNODE_TEST_FILE_RW2
, rc
);
205 rc
= vn_rdwr(UIO_READ
, vp
, buf2
, strlen(buf1
), 0,
206 UIO_SYSSPACE
, 0, RLIM64_INFINITY
, 0, NULL
);
208 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
,
209 "Failed vn_rdwr read of test file: %s (%d)\n",
210 SPLAT_VNODE_TEST_FILE_RW2
, rc
);
214 if (strncmp(buf1
, buf2
, strlen(buf1
))) {
216 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
,
217 "Failed strncmp data written does not match "
218 "data read\nWrote: %sRead: %s\n", buf1
, buf2
);
223 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
, "Wrote to %s: %s",
224 SPLAT_VNODE_TEST_FILE_RW1
, buf1
);
225 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
, "Read from %s: %s",
226 SPLAT_VNODE_TEST_FILE_RW2
, buf2
);
227 splat_vprint(file
, SPLAT_VNODE_TEST4_NAME
, "Successfully renamed "
228 "test file %s -> %s and verified data pattern\n",
229 SPLAT_VNODE_TEST_FILE_RW1
, SPLAT_VNODE_TEST_FILE_RW2
);
231 VOP_CLOSE(vp
, 0, 0, 0, 0, 0);
234 vn_remove(SPLAT_VNODE_TEST_FILE_RW1
, UIO_SYSSPACE
, RMFILE
);
235 vn_remove(SPLAT_VNODE_TEST_FILE_RW2
, UIO_SYSSPACE
, RMFILE
);
238 } /* splat_vnode_test4() */
241 splat_vnode_test5(struct file
*file
, void *arg
)
247 if ((rc
= vn_open(SPLAT_VNODE_TEST_FILE
, UIO_SYSSPACE
,
248 FREAD
, 0644, &vp
, 0, 0))) {
249 splat_vprint(file
, SPLAT_VNODE_TEST5_NAME
,
250 "Failed to vn_open test file: %s (%d)\n",
251 SPLAT_VNODE_TEST_FILE
, rc
);
255 rc
= VOP_GETATTR(vp
, &vap
, 0, 0, NULL
);
257 splat_vprint(file
, SPLAT_VNODE_TEST5_NAME
,
258 "Failed to vn_getattr test file: %s (%d)\n",
259 SPLAT_VNODE_TEST_FILE
, rc
);
263 if (vap
.va_type
!= VREG
) {
265 splat_vprint(file
, SPLAT_VNODE_TEST5_NAME
,
266 "Failed expected regular file type "
267 "(%d != VREG): %s (%d)\n", vap
.va_type
,
268 SPLAT_VNODE_TEST_FILE
, rc
);
272 splat_vprint(file
, SPLAT_VNODE_TEST1_NAME
, "Successfully "
273 "vn_getattr'ed test file: %s\n", SPLAT_VNODE_TEST_FILE
);
276 VOP_CLOSE(vp
, 0, 0, 0, 0, 0);
280 } /* splat_vnode_test5() */
283 splat_vnode_test6(struct file
*file
, void *arg
)
286 char buf
[32] = "SPL VNode Interface Test File\n";
289 if ((rc
= vn_open(SPLAT_VNODE_TEST_FILE_RW
, UIO_SYSSPACE
,
290 FWRITE
| FREAD
| FCREAT
| FEXCL
, 0644, &vp
, 0, 0))) {
291 splat_vprint(file
, SPLAT_VNODE_TEST6_NAME
,
292 "Failed to vn_open test file: %s (%d)\n",
293 SPLAT_VNODE_TEST_FILE_RW
, rc
);
297 rc
= vn_rdwr(UIO_WRITE
, vp
, buf
, strlen(buf
), 0,
298 UIO_SYSSPACE
, 0, RLIM64_INFINITY
, 0, NULL
);
300 splat_vprint(file
, SPLAT_VNODE_TEST6_NAME
,
301 "Failed vn_rdwr write of test file: %s (%d)\n",
302 SPLAT_VNODE_TEST_FILE_RW
, rc
);
306 rc
= vn_fsync(vp
, 0, 0, 0);
308 splat_vprint(file
, SPLAT_VNODE_TEST6_NAME
,
309 "Failed vn_fsync of test file: %s (%d)\n",
310 SPLAT_VNODE_TEST_FILE_RW
, rc
);
315 splat_vprint(file
, SPLAT_VNODE_TEST6_NAME
, "Successfully "
316 "fsync'ed test file %s\n", SPLAT_VNODE_TEST_FILE_RW
);
318 VOP_CLOSE(vp
, 0, 0, 0, 0, 0);
320 vn_remove(SPLAT_VNODE_TEST_FILE_RW
, UIO_SYSSPACE
, RMFILE
);
323 } /* splat_vnode_test6() */
325 /* Basically a slightly modified version of sys_close() */
330 struct files_struct
*files
= current
->files
;
333 spin_lock(&files
->file_lock
);
334 fdt
= files_fdtable(files
);
336 if (fd
>= fdt
->max_fds
)
343 rcu_assign_pointer(fdt
->fd
[fd
], NULL
);
344 FD_CLR(fd
, fdt
->close_on_exec
);
346 /* Dropping the lock here exposes a minor race but it allows me
347 * to use the existing kernel interfaces for this, and for a test
348 * case I think that's reasonable. */
349 spin_unlock(&files
->file_lock
);
353 spin_unlock(&files
->file_lock
);
355 } /* fd_uninstall() */
358 splat_vnode_test7(struct file
*file
, void *arg
)
360 char buf1
[32] = "SPL VNode Interface Test File\n";
366 /* Prep work needed to test getf/releasef */
367 fd
= get_unused_fd();
369 splat_vprint(file
, SPLAT_VNODE_TEST7_NAME
,
370 "Failed to get unused fd (%d)\n", fd
);
374 lfp
= filp_open(SPLAT_VNODE_TEST_FILE_RW
, O_RDWR
|O_CREAT
|O_EXCL
, 0644);
378 splat_vprint(file
, SPLAT_VNODE_TEST7_NAME
,
379 "Failed to filp_open: %s (%d)\n",
380 SPLAT_VNODE_TEST_FILE_RW
, rc
);
384 /* Pair up the new fd and lfp in the current context, this allows
385 * getf to lookup the file struct simply by the known open fd */
388 /* Actual getf()/releasef() test */
392 splat_vprint(file
, SPLAT_VNODE_TEST7_NAME
,
393 "Failed to getf fd %d: (%d)\n", fd
, rc
);
397 rc
= vn_rdwr(UIO_WRITE
, fp
->f_vnode
, buf1
, strlen(buf1
), 0,
398 UIO_SYSSPACE
, 0, RLIM64_INFINITY
, 0, NULL
);
400 splat_vprint(file
, SPLAT_VNODE_TEST7_NAME
,
401 "Failed vn_rdwr write of test file: %s (%d)\n",
402 SPLAT_VNODE_TEST_FILE_RW
, rc
);
406 rc
= vn_rdwr(UIO_READ
, fp
->f_vnode
, buf2
, strlen(buf1
), 0,
407 UIO_SYSSPACE
, 0, RLIM64_INFINITY
, 0, NULL
);
409 splat_vprint(file
, SPLAT_VNODE_TEST7_NAME
,
410 "Failed vn_rdwr read of test file: %s (%d)\n",
411 SPLAT_VNODE_TEST_FILE_RW
, rc
);
415 if (strncmp(buf1
, buf2
, strlen(buf1
))) {
417 splat_vprint(file
, SPLAT_VNODE_TEST7_NAME
,
418 "Failed strncmp data written does not match "
419 "data read\nWrote: %sRead: %s\n", buf1
, buf2
);
424 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
, "Wrote: %s", buf1
);
425 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
, "Read: %s", buf2
);
426 splat_vprint(file
, SPLAT_VNODE_TEST3_NAME
, "Successfully wrote and "
427 "read expected data pattern to test file: %s\n",
428 SPLAT_VNODE_TEST_FILE_RW
);
433 vn_remove(SPLAT_VNODE_TEST_FILE_RW
, UIO_SYSSPACE
, RMFILE
);
436 } /* splat_vnode_test7() */
439 splat_vnode_init(void)
441 splat_subsystem_t
*sub
;
443 sub
= kmalloc(sizeof(*sub
), GFP_KERNEL
);
447 memset(sub
, 0, sizeof(*sub
));
448 strncpy(sub
->desc
.name
, SPLAT_VNODE_NAME
, SPLAT_NAME_SIZE
);
449 strncpy(sub
->desc
.desc
, SPLAT_VNODE_DESC
, SPLAT_DESC_SIZE
);
450 INIT_LIST_HEAD(&sub
->subsystem_list
);
451 INIT_LIST_HEAD(&sub
->test_list
);
452 spin_lock_init(&sub
->test_lock
);
453 sub
->desc
.id
= SPLAT_SUBSYSTEM_VNODE
;
455 SPLAT_TEST_INIT(sub
, SPLAT_VNODE_TEST1_NAME
, SPLAT_VNODE_TEST1_DESC
,
456 SPLAT_VNODE_TEST1_ID
, splat_vnode_test1
);
457 SPLAT_TEST_INIT(sub
, SPLAT_VNODE_TEST2_NAME
, SPLAT_VNODE_TEST2_DESC
,
458 SPLAT_VNODE_TEST2_ID
, splat_vnode_test2
);
459 SPLAT_TEST_INIT(sub
, SPLAT_VNODE_TEST3_NAME
, SPLAT_VNODE_TEST3_DESC
,
460 SPLAT_VNODE_TEST3_ID
, splat_vnode_test3
);
461 SPLAT_TEST_INIT(sub
, SPLAT_VNODE_TEST4_NAME
, SPLAT_VNODE_TEST4_DESC
,
462 SPLAT_VNODE_TEST4_ID
, splat_vnode_test4
);
463 SPLAT_TEST_INIT(sub
, SPLAT_VNODE_TEST5_NAME
, SPLAT_VNODE_TEST5_DESC
,
464 SPLAT_VNODE_TEST5_ID
, splat_vnode_test5
);
465 SPLAT_TEST_INIT(sub
, SPLAT_VNODE_TEST6_NAME
, SPLAT_VNODE_TEST6_DESC
,
466 SPLAT_VNODE_TEST6_ID
, splat_vnode_test6
);
467 SPLAT_TEST_INIT(sub
, SPLAT_VNODE_TEST7_NAME
, SPLAT_VNODE_TEST7_DESC
,
468 SPLAT_VNODE_TEST7_ID
, splat_vnode_test7
);
471 } /* splat_vnode_init() */
474 splat_vnode_fini(splat_subsystem_t
*sub
)
478 SPLAT_TEST_FINI(sub
, SPLAT_VNODE_TEST7_ID
);
479 SPLAT_TEST_FINI(sub
, SPLAT_VNODE_TEST6_ID
);
480 SPLAT_TEST_FINI(sub
, SPLAT_VNODE_TEST5_ID
);
481 SPLAT_TEST_FINI(sub
, SPLAT_VNODE_TEST4_ID
);
482 SPLAT_TEST_FINI(sub
, SPLAT_VNODE_TEST3_ID
);
483 SPLAT_TEST_FINI(sub
, SPLAT_VNODE_TEST2_ID
);
484 SPLAT_TEST_FINI(sub
, SPLAT_VNODE_TEST1_ID
);
487 } /* splat_vnode_fini() */
492 return SPLAT_SUBSYSTEM_VNODE
;
493 } /* splat_vnode_id() */