2008-05-26 04:38:26 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the SPL: Solaris Porting Layer.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2008 Lawrence Livermore National Security, LLC.
|
|
|
|
* Produced at Lawrence Livermore National Laboratory
|
|
|
|
* Written by:
|
|
|
|
* Brian Behlendorf <behlendorf1@llnl.gov>,
|
|
|
|
* Herb Wartens <wartens2@llnl.gov>,
|
|
|
|
* Jim Garlick <garlick@llnl.gov>
|
|
|
|
* UCRL-CODE-235197
|
|
|
|
*
|
|
|
|
* This is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2008-03-12 20:52:46 +00:00
|
|
|
#include "splat-internal.h"
|
2008-03-18 23:20:30 +00:00
|
|
|
#include <linux/rcupdate.h>
|
2008-03-12 20:52:46 +00:00
|
|
|
|
|
|
|
#define SPLAT_SUBSYSTEM_VNODE 0x0900
|
|
|
|
#define SPLAT_VNODE_NAME "vnode"
|
|
|
|
#define SPLAT_VNODE_DESC "Kernel Vnode Tests"
|
|
|
|
|
|
|
|
#define SPLAT_VNODE_TEST1_ID 0x0901
|
|
|
|
#define SPLAT_VNODE_TEST1_NAME "vn_open"
|
|
|
|
#define SPLAT_VNODE_TEST1_DESC "Vn_open Test"
|
|
|
|
|
|
|
|
#define SPLAT_VNODE_TEST2_ID 0x0902
|
|
|
|
#define SPLAT_VNODE_TEST2_NAME "vn_openat"
|
|
|
|
#define SPLAT_VNODE_TEST2_DESC "Vn_openat Test"
|
|
|
|
|
|
|
|
#define SPLAT_VNODE_TEST3_ID 0x0903
|
|
|
|
#define SPLAT_VNODE_TEST3_NAME "vn_rdwr"
|
|
|
|
#define SPLAT_VNODE_TEST3_DESC "Vn_rdwrt Test"
|
|
|
|
|
|
|
|
#define SPLAT_VNODE_TEST4_ID 0x0904
|
|
|
|
#define SPLAT_VNODE_TEST4_NAME "vn_rename"
|
|
|
|
#define SPLAT_VNODE_TEST4_DESC "Vn_rename Test"
|
|
|
|
|
|
|
|
#define SPLAT_VNODE_TEST5_ID 0x0905
|
|
|
|
#define SPLAT_VNODE_TEST5_NAME "vn_getattr"
|
|
|
|
#define SPLAT_VNODE_TEST5_DESC "Vn_getattr Test"
|
|
|
|
|
|
|
|
#define SPLAT_VNODE_TEST6_ID 0x0906
|
|
|
|
#define SPLAT_VNODE_TEST6_NAME "vn_sync"
|
|
|
|
#define SPLAT_VNODE_TEST6_DESC "Vn_sync Test"
|
|
|
|
|
2008-03-18 23:20:30 +00:00
|
|
|
#define SPLAT_VNODE_TEST7_ID 0x0907
|
2008-03-20 23:30:15 +00:00
|
|
|
#define SPLAT_VNODE_TEST7_NAME "vn_getf"
|
|
|
|
#define SPLAT_VNODE_TEST7_DESC "vn_getf/vn_releasef Test"
|
2008-03-18 23:20:30 +00:00
|
|
|
|
2008-03-12 20:52:46 +00:00
|
|
|
#define SPLAT_VNODE_TEST_FILE "/etc/fstab"
|
|
|
|
#define SPLAT_VNODE_TEST_FILE_AT "etc/fstab"
|
|
|
|
#define SPLAT_VNODE_TEST_FILE_RW "/tmp/spl.vnode.tmp"
|
|
|
|
#define SPLAT_VNODE_TEST_FILE_RW1 "/tmp/spl.vnode.tmp.1"
|
|
|
|
#define SPLAT_VNODE_TEST_FILE_RW2 "/tmp/spl.vnode.tmp.2"
|
|
|
|
|
|
|
|
static int
|
|
|
|
splat_vnode_test1(struct file *file, void *arg)
|
|
|
|
{
|
|
|
|
vnode_t *vp;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE, UIO_SYSSPACE,
|
|
|
|
FREAD, 0644, &vp, 0, 0))) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST1_NAME,
|
|
|
|
"Failed to vn_open test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = VOP_CLOSE(vp, 0, 0, 0, 0, 0);
|
|
|
|
VN_RELE(vp);
|
|
|
|
|
|
|
|
if (rc) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST1_NAME,
|
|
|
|
"Failed to vn_close test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST1_NAME, "Successfully vn_open'ed "
|
|
|
|
"and vn_closed test file: %s\n", SPLAT_VNODE_TEST_FILE);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
} /* splat_vnode_test1() */
|
|
|
|
|
|
|
|
static int
|
|
|
|
splat_vnode_test2(struct file *file, void *arg)
|
|
|
|
{
|
|
|
|
vnode_t *vp;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = vn_openat(SPLAT_VNODE_TEST_FILE_AT, UIO_SYSSPACE,
|
|
|
|
FREAD, 0644, &vp, 0, 0, rootdir, 0))) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST2_NAME,
|
|
|
|
"Failed to vn_openat test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = VOP_CLOSE(vp, 0, 0, 0, 0, 0);
|
|
|
|
VN_RELE(vp);
|
|
|
|
|
|
|
|
if (rc) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST2_NAME,
|
|
|
|
"Failed to vn_close test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST2_NAME, "Successfully vn_openat'ed "
|
|
|
|
"and vn_closed test file: %s\n", SPLAT_VNODE_TEST_FILE);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
} /* splat_vnode_test2() */
|
|
|
|
|
|
|
|
static int
|
|
|
|
splat_vnode_test3(struct file *file, void *arg)
|
|
|
|
{
|
|
|
|
vnode_t *vp;
|
|
|
|
char buf1[32] = "SPL VNode Interface Test File\n";
|
|
|
|
char buf2[32] = "";
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE,
|
|
|
|
FWRITE | FREAD | FCREAT | FEXCL,
|
|
|
|
0644, &vp, 0, 0))) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
|
|
|
|
"Failed to vn_open test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_rdwr(UIO_WRITE, vp, buf1, strlen(buf1), 0,
|
|
|
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
|
|
|
|
if (rc < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
|
|
|
|
"Failed vn_rdwr write of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_rdwr(UIO_READ, vp, buf2, strlen(buf1), 0,
|
|
|
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
|
|
|
|
if (rc < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
|
|
|
|
"Failed vn_rdwr read of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp(buf1, buf2, strlen(buf1))) {
|
2008-03-18 23:20:30 +00:00
|
|
|
rc = -EINVAL;
|
2008-03-12 20:52:46 +00:00
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
|
|
|
|
"Failed strncmp data written does not match "
|
|
|
|
"data read\nWrote: %sRead: %s\n", buf1, buf2);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Wrote: %s", buf1);
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Read: %s", buf2);
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Successfully wrote and "
|
|
|
|
"read expected data pattern to test file: %s\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW);
|
|
|
|
|
|
|
|
out:
|
|
|
|
VOP_CLOSE(vp, 0, 0, 0, 0, 0);
|
|
|
|
VN_RELE(vp);
|
2008-03-12 21:33:28 +00:00
|
|
|
vn_remove(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE, RMFILE);
|
2008-03-12 20:52:46 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
} /* splat_vnode_test3() */
|
|
|
|
|
|
|
|
static int
|
|
|
|
splat_vnode_test4(struct file *file, void *arg)
|
|
|
|
{
|
|
|
|
vnode_t *vp;
|
|
|
|
char buf1[32] = "SPL VNode Interface Test File\n";
|
|
|
|
char buf2[32] = "";
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW1, UIO_SYSSPACE,
|
|
|
|
FWRITE | FREAD | FCREAT | FEXCL, 0644, &vp, 0, 0))) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
|
|
|
|
"Failed to vn_open test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW1, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_rdwr(UIO_WRITE, vp, buf1, strlen(buf1), 0,
|
|
|
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
|
|
|
|
if (rc < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
|
|
|
|
"Failed vn_rdwr write of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW1, rc);
|
|
|
|
goto out2;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOP_CLOSE(vp, 0, 0, 0, 0, 0);
|
|
|
|
VN_RELE(vp);
|
|
|
|
|
|
|
|
rc = vn_rename(SPLAT_VNODE_TEST_FILE_RW1,SPLAT_VNODE_TEST_FILE_RW2,0);
|
|
|
|
if (rc) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Failed vn_rename "
|
|
|
|
"%s -> %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW1,
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW2, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW2, UIO_SYSSPACE,
|
|
|
|
FREAD | FEXCL, 0644, &vp, 0, 0))) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
|
|
|
|
"Failed to vn_open test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW2, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_rdwr(UIO_READ, vp, buf2, strlen(buf1), 0,
|
|
|
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
|
|
|
|
if (rc < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
|
|
|
|
"Failed vn_rdwr read of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW2, rc);
|
|
|
|
goto out2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp(buf1, buf2, strlen(buf1))) {
|
|
|
|
rc = EINVAL;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME,
|
|
|
|
"Failed strncmp data written does not match "
|
|
|
|
"data read\nWrote: %sRead: %s\n", buf1, buf2);
|
|
|
|
goto out2;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Wrote to %s: %s",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW1, buf1);
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Read from %s: %s",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW2, buf2);
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST4_NAME, "Successfully renamed "
|
|
|
|
"test file %s -> %s and verified data pattern\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW1, SPLAT_VNODE_TEST_FILE_RW2);
|
|
|
|
out2:
|
|
|
|
VOP_CLOSE(vp, 0, 0, 0, 0, 0);
|
|
|
|
VN_RELE(vp);
|
|
|
|
out:
|
2008-03-12 21:33:28 +00:00
|
|
|
vn_remove(SPLAT_VNODE_TEST_FILE_RW1, UIO_SYSSPACE, RMFILE);
|
|
|
|
vn_remove(SPLAT_VNODE_TEST_FILE_RW2, UIO_SYSSPACE, RMFILE);
|
2008-03-12 20:52:46 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
} /* splat_vnode_test4() */
|
|
|
|
|
|
|
|
static int
|
|
|
|
splat_vnode_test5(struct file *file, void *arg)
|
|
|
|
{
|
|
|
|
vnode_t *vp;
|
|
|
|
vattr_t vap;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE, UIO_SYSSPACE,
|
|
|
|
FREAD, 0644, &vp, 0, 0))) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST5_NAME,
|
|
|
|
"Failed to vn_open test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = VOP_GETATTR(vp, &vap, 0, 0, NULL);
|
|
|
|
if (rc) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST5_NAME,
|
|
|
|
"Failed to vn_getattr test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vap.va_type != VREG) {
|
|
|
|
rc = -EINVAL;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST5_NAME,
|
|
|
|
"Failed expected regular file type "
|
|
|
|
"(%d != VREG): %s (%d)\n", vap.va_type,
|
|
|
|
SPLAT_VNODE_TEST_FILE, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST1_NAME, "Successfully "
|
|
|
|
"vn_getattr'ed test file: %s\n", SPLAT_VNODE_TEST_FILE);
|
|
|
|
|
|
|
|
out:
|
|
|
|
VOP_CLOSE(vp, 0, 0, 0, 0, 0);
|
|
|
|
VN_RELE(vp);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
} /* splat_vnode_test5() */
|
|
|
|
|
|
|
|
static int
|
|
|
|
splat_vnode_test6(struct file *file, void *arg)
|
|
|
|
{
|
|
|
|
vnode_t *vp;
|
|
|
|
char buf[32] = "SPL VNode Interface Test File\n";
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE,
|
2008-04-04 17:08:12 +00:00
|
|
|
FWRITE | FCREAT | FEXCL, 0644, &vp, 0, 0))) {
|
2008-03-12 20:52:46 +00:00
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
|
|
|
|
"Failed to vn_open test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_rdwr(UIO_WRITE, vp, buf, strlen(buf), 0,
|
|
|
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
|
|
|
|
if (rc < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
|
|
|
|
"Failed vn_rdwr write of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_fsync(vp, 0, 0, 0);
|
|
|
|
if (rc) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
|
|
|
|
"Failed vn_fsync of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST6_NAME, "Successfully "
|
|
|
|
"fsync'ed test file %s\n", SPLAT_VNODE_TEST_FILE_RW);
|
|
|
|
out:
|
|
|
|
VOP_CLOSE(vp, 0, 0, 0, 0, 0);
|
|
|
|
VN_RELE(vp);
|
2008-03-12 21:33:28 +00:00
|
|
|
vn_remove(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE, RMFILE);
|
2008-03-12 20:52:46 +00:00
|
|
|
|
|
|
|
return rc;
|
2008-03-18 23:20:30 +00:00
|
|
|
} /* splat_vnode_test6() */
|
|
|
|
|
|
|
|
/* Basically a slightly modified version of sys_close() */
|
|
|
|
static int
|
|
|
|
fd_uninstall(int fd)
|
|
|
|
{
|
|
|
|
struct file *fp;
|
|
|
|
struct files_struct *files = current->files;
|
2008-08-11 23:47:44 +00:00
|
|
|
#ifdef HAVE_FILES_FDTABLE
|
2008-03-18 23:20:30 +00:00
|
|
|
struct fdtable *fdt;
|
|
|
|
|
|
|
|
spin_lock(&files->file_lock);
|
|
|
|
fdt = files_fdtable(files);
|
|
|
|
|
|
|
|
if (fd >= fdt->max_fds)
|
|
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
fp = fdt->fd[fd];
|
|
|
|
if (!fp)
|
|
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
rcu_assign_pointer(fdt->fd[fd], NULL);
|
|
|
|
FD_CLR(fd, fdt->close_on_exec);
|
2008-08-11 22:13:47 +00:00
|
|
|
#else
|
2008-08-11 23:47:44 +00:00
|
|
|
spin_lock(&files->file_lock);
|
2008-08-11 22:13:47 +00:00
|
|
|
if (fd >= files->max_fds)
|
|
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
fp = files->fd[fd];
|
|
|
|
if (!fp)
|
|
|
|
goto out_unlock;
|
2008-03-18 23:20:30 +00:00
|
|
|
|
2008-08-11 22:13:47 +00:00
|
|
|
files->fd[fd] = NULL;
|
|
|
|
FD_CLR(fd, files->close_on_exec);
|
|
|
|
#endif
|
|
|
|
/* Dropping the lock here exposes a minor race but it allows me
|
|
|
|
* to use the existing kernel interfaces for this, and for a test
|
|
|
|
* case I think that's reasonable. */
|
2008-03-18 23:20:30 +00:00
|
|
|
spin_unlock(&files->file_lock);
|
|
|
|
put_unused_fd(fd);
|
2008-06-03 20:58:55 +00:00
|
|
|
return 0;
|
2008-03-18 23:20:30 +00:00
|
|
|
|
|
|
|
out_unlock:
|
|
|
|
spin_unlock(&files->file_lock);
|
|
|
|
return -EBADF;
|
|
|
|
} /* fd_uninstall() */
|
|
|
|
|
|
|
|
static int
|
|
|
|
splat_vnode_test7(struct file *file, void *arg)
|
|
|
|
{
|
|
|
|
char buf1[32] = "SPL VNode Interface Test File\n";
|
|
|
|
char buf2[32] = "";
|
|
|
|
struct file *lfp;
|
|
|
|
file_t *fp;
|
|
|
|
int rc, fd;
|
|
|
|
|
|
|
|
/* Prep work needed to test getf/releasef */
|
|
|
|
fd = get_unused_fd();
|
|
|
|
if (fd < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST7_NAME,
|
|
|
|
"Failed to get unused fd (%d)\n", fd);
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
lfp = filp_open(SPLAT_VNODE_TEST_FILE_RW, O_RDWR|O_CREAT|O_EXCL, 0644);
|
|
|
|
if (IS_ERR(lfp)) {
|
|
|
|
put_unused_fd(fd);
|
|
|
|
rc = PTR_ERR(lfp);
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST7_NAME,
|
|
|
|
"Failed to filp_open: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Pair up the new fd and lfp in the current context, this allows
|
|
|
|
* getf to lookup the file struct simply by the known open fd */
|
|
|
|
fd_install(fd, lfp);
|
|
|
|
|
|
|
|
/* Actual getf()/releasef() test */
|
|
|
|
fp = vn_getf(fd);
|
|
|
|
if (fp == NULL) {
|
|
|
|
rc = -EINVAL;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST7_NAME,
|
|
|
|
"Failed to getf fd %d: (%d)\n", fd, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_rdwr(UIO_WRITE, fp->f_vnode, buf1, strlen(buf1), 0,
|
|
|
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
|
|
|
|
if (rc < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST7_NAME,
|
|
|
|
"Failed vn_rdwr write of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vn_rdwr(UIO_READ, fp->f_vnode, buf2, strlen(buf1), 0,
|
|
|
|
UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
|
|
|
|
if (rc < 0) {
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST7_NAME,
|
|
|
|
"Failed vn_rdwr read of test file: %s (%d)\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp(buf1, buf2, strlen(buf1))) {
|
|
|
|
rc = -EINVAL;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST7_NAME,
|
|
|
|
"Failed strncmp data written does not match "
|
|
|
|
"data read\nWrote: %sRead: %s\n", buf1, buf2);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Wrote: %s", buf1);
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Read: %s", buf2);
|
|
|
|
splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Successfully wrote and "
|
|
|
|
"read expected data pattern to test file: %s\n",
|
|
|
|
SPLAT_VNODE_TEST_FILE_RW);
|
|
|
|
out:
|
|
|
|
vn_releasef(fd);
|
|
|
|
fd_uninstall(fd);
|
|
|
|
filp_close(lfp, 0);
|
|
|
|
vn_remove(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE, RMFILE);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
} /* splat_vnode_test7() */
|
2008-03-12 20:52:46 +00:00
|
|
|
|
|
|
|
splat_subsystem_t *
|
|
|
|
splat_vnode_init(void)
|
|
|
|
{
|
|
|
|
splat_subsystem_t *sub;
|
|
|
|
|
|
|
|
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
|
|
|
|
if (sub == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memset(sub, 0, sizeof(*sub));
|
|
|
|
strncpy(sub->desc.name, SPLAT_VNODE_NAME, SPLAT_NAME_SIZE);
|
|
|
|
strncpy(sub->desc.desc, SPLAT_VNODE_DESC, SPLAT_DESC_SIZE);
|
|
|
|
INIT_LIST_HEAD(&sub->subsystem_list);
|
|
|
|
INIT_LIST_HEAD(&sub->test_list);
|
|
|
|
spin_lock_init(&sub->test_lock);
|
|
|
|
sub->desc.id = SPLAT_SUBSYSTEM_VNODE;
|
|
|
|
|
|
|
|
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST1_NAME, SPLAT_VNODE_TEST1_DESC,
|
|
|
|
SPLAT_VNODE_TEST1_ID, splat_vnode_test1);
|
|
|
|
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST2_NAME, SPLAT_VNODE_TEST2_DESC,
|
|
|
|
SPLAT_VNODE_TEST2_ID, splat_vnode_test2);
|
|
|
|
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST3_NAME, SPLAT_VNODE_TEST3_DESC,
|
|
|
|
SPLAT_VNODE_TEST3_ID, splat_vnode_test3);
|
|
|
|
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST4_NAME, SPLAT_VNODE_TEST4_DESC,
|
|
|
|
SPLAT_VNODE_TEST4_ID, splat_vnode_test4);
|
|
|
|
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST5_NAME, SPLAT_VNODE_TEST5_DESC,
|
|
|
|
SPLAT_VNODE_TEST5_ID, splat_vnode_test5);
|
|
|
|
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST6_NAME, SPLAT_VNODE_TEST6_DESC,
|
|
|
|
SPLAT_VNODE_TEST6_ID, splat_vnode_test6);
|
2008-03-18 23:20:30 +00:00
|
|
|
SPLAT_TEST_INIT(sub, SPLAT_VNODE_TEST7_NAME, SPLAT_VNODE_TEST7_DESC,
|
|
|
|
SPLAT_VNODE_TEST7_ID, splat_vnode_test7);
|
2008-03-12 20:52:46 +00:00
|
|
|
|
|
|
|
return sub;
|
|
|
|
} /* splat_vnode_init() */
|
|
|
|
|
|
|
|
void
|
|
|
|
splat_vnode_fini(splat_subsystem_t *sub)
|
|
|
|
{
|
|
|
|
ASSERT(sub);
|
|
|
|
|
2008-03-18 23:20:30 +00:00
|
|
|
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST7_ID);
|
2008-03-12 20:52:46 +00:00
|
|
|
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST6_ID);
|
|
|
|
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST5_ID);
|
|
|
|
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST4_ID);
|
|
|
|
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST3_ID);
|
|
|
|
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST2_ID);
|
|
|
|
SPLAT_TEST_FINI(sub, SPLAT_VNODE_TEST1_ID);
|
|
|
|
|
|
|
|
kfree(sub);
|
|
|
|
} /* splat_vnode_fini() */
|
|
|
|
|
|
|
|
int
|
|
|
|
splat_vnode_id(void)
|
|
|
|
{
|
|
|
|
return SPLAT_SUBSYSTEM_VNODE;
|
|
|
|
} /* splat_vnode_id() */
|