mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
- Fix write-only behavior in vn-open()
- Ensure we have at least 1 write-only splat test - Fix return codes for vn_* Solaris does not use negative return codes in the kernel. So linux errno's must be inverted. git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@67 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
This commit is contained in:
parent
968eccd1d1
commit
728b9dd800
@ -52,7 +52,7 @@ vn_alloc(int flag)
|
|||||||
vp->v_type = 0;
|
vp->v_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (vp);
|
return vp;
|
||||||
} /* vn_alloc() */
|
} /* vn_alloc() */
|
||||||
EXPORT_SYMBOL(vn_alloc);
|
EXPORT_SYMBOL(vn_alloc);
|
||||||
|
|
||||||
@ -69,9 +69,10 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
|
|||||||
{
|
{
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
struct kstat stat;
|
struct kstat stat;
|
||||||
int rc, saved_umask, flags_rw;
|
int rc, saved_umask;
|
||||||
vnode_t *vp;
|
vnode_t *vp;
|
||||||
|
|
||||||
|
BUG_ON(!(flags & (FWRITE | FREAD)));
|
||||||
BUG_ON(seg != UIO_SYSSPACE);
|
BUG_ON(seg != UIO_SYSSPACE);
|
||||||
BUG_ON(!vpp);
|
BUG_ON(!vpp);
|
||||||
*vpp = NULL;
|
*vpp = NULL;
|
||||||
@ -79,13 +80,12 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
|
|||||||
if (!(flags & FCREAT) && (flags & FWRITE))
|
if (!(flags & FCREAT) && (flags & FWRITE))
|
||||||
flags |= FEXCL;
|
flags |= FEXCL;
|
||||||
|
|
||||||
flags_rw = flags & (FWRITE | FREAD);
|
/* Note for filp_open() the two low bits must be remapped to mean:
|
||||||
flags &= ~(FWRITE | FREAD);
|
* 01 - read-only -> 00 read-only
|
||||||
switch (flags_rw) {
|
* 10 - write-only -> 01 write-only
|
||||||
case FWRITE: flags |= O_WRONLY;
|
* 11 - read-write -> 10 read-write
|
||||||
case FREAD: flags |= O_RDONLY;
|
*/
|
||||||
case (FWRITE | FREAD): flags |= O_RDWR;
|
flags--;
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & FCREAT)
|
if (flags & FCREAT)
|
||||||
saved_umask = xchg(¤t->fs->umask, 0);
|
saved_umask = xchg(¤t->fs->umask, 0);
|
||||||
@ -96,18 +96,18 @@ vn_open(const char *path, uio_seg_t seg, int flags, int mode,
|
|||||||
(void)xchg(¤t->fs->umask, saved_umask);
|
(void)xchg(¤t->fs->umask, saved_umask);
|
||||||
|
|
||||||
if (IS_ERR(fp))
|
if (IS_ERR(fp))
|
||||||
return PTR_ERR(fp);
|
return -PTR_ERR(fp);
|
||||||
|
|
||||||
rc = vfs_getattr(fp->f_vfsmnt, fp->f_dentry, &stat);
|
rc = vfs_getattr(fp->f_vfsmnt, fp->f_dentry, &stat);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
filp_close(fp, 0);
|
filp_close(fp, 0);
|
||||||
return rc;
|
return -rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
vp = vn_alloc(KM_SLEEP);
|
vp = vn_alloc(KM_SLEEP);
|
||||||
if (!vp) {
|
if (!vp) {
|
||||||
filp_close(fp, 0);
|
filp_close(fp, 0);
|
||||||
return -ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_enter(&vp->v_lock);
|
mutex_enter(&vp->v_lock);
|
||||||
@ -131,7 +131,7 @@ vn_openat(const char *path, uio_seg_t seg, int flags, int mode,
|
|||||||
|
|
||||||
realpath = kmalloc(strlen(path) + 2, GFP_KERNEL);
|
realpath = kmalloc(strlen(path) + 2, GFP_KERNEL);
|
||||||
if (!realpath)
|
if (!realpath)
|
||||||
return -ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
sprintf(realpath, "/%s", path);
|
sprintf(realpath, "/%s", path);
|
||||||
rc = vn_open(realpath, seg, flags, mode, vpp, x1, x2);
|
rc = vn_open(realpath, seg, flags, mode, vpp, x1, x2);
|
||||||
@ -175,13 +175,13 @@ vn_rdwr(uio_rw_t uio, vnode_t *vp, void *addr, ssize_t len, offset_t off,
|
|||||||
set_fs(saved_fs);
|
set_fs(saved_fs);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return -rc;
|
||||||
|
|
||||||
if (residp) {
|
if (residp) {
|
||||||
*residp = len - rc;
|
*residp = len - rc;
|
||||||
} else {
|
} else {
|
||||||
if (rc != len)
|
if (rc != len)
|
||||||
return -EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -199,7 +199,7 @@ vn_close(vnode_t *vp, int flags, int x1, int x2, void *x3, void *x4)
|
|||||||
rc = filp_close(vp->v_file, 0);
|
rc = filp_close(vp->v_file, 0);
|
||||||
vn_free(vp);
|
vn_free(vp);
|
||||||
|
|
||||||
return rc;
|
return -rc;
|
||||||
} /* vn_close() */
|
} /* vn_close() */
|
||||||
EXPORT_SYMBOL(vn_close);
|
EXPORT_SYMBOL(vn_close);
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ exit2:
|
|||||||
exit1:
|
exit1:
|
||||||
path_release(&nd);
|
path_release(&nd);
|
||||||
exit:
|
exit:
|
||||||
return rc;
|
return -rc;
|
||||||
|
|
||||||
slashes:
|
slashes:
|
||||||
rc = !dentry->d_inode ? -ENOENT :
|
rc = !dentry->d_inode ? -ENOENT :
|
||||||
@ -338,7 +338,7 @@ exit2:
|
|||||||
exit1:
|
exit1:
|
||||||
path_release(&oldnd);
|
path_release(&oldnd);
|
||||||
exit:
|
exit:
|
||||||
return rc;
|
return -rc;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vn_rename);
|
EXPORT_SYMBOL(vn_rename);
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4)
|
|||||||
|
|
||||||
rc = vfs_getattr(fp->f_vfsmnt, fp->f_dentry, &stat);
|
rc = vfs_getattr(fp->f_vfsmnt, fp->f_dentry, &stat);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return -rc;
|
||||||
|
|
||||||
vap->va_type = vn_get_sol_type(stat.mode);
|
vap->va_type = vn_get_sol_type(stat.mode);
|
||||||
vap->va_mode = stat.mode;
|
vap->va_mode = stat.mode;
|
||||||
@ -377,7 +377,7 @@ vn_getattr(vnode_t *vp, vattr_t *vap, int flags, void *x3, void *x4)
|
|||||||
vap->va_rdev = stat.rdev;
|
vap->va_rdev = stat.rdev;
|
||||||
vap->va_blocks = stat.blocks;
|
vap->va_blocks = stat.blocks;
|
||||||
|
|
||||||
return rc;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(vn_getattr);
|
EXPORT_SYMBOL(vn_getattr);
|
||||||
|
|
||||||
@ -391,7 +391,7 @@ int vn_fsync(vnode_t *vp, int flags, void *x3, void *x4)
|
|||||||
if (flags & FDSYNC)
|
if (flags & FDSYNC)
|
||||||
datasync = 1;
|
datasync = 1;
|
||||||
|
|
||||||
return file_fsync(vp->v_file, vp->v_file->f_dentry, datasync);
|
return -file_fsync(vp->v_file, vp->v_file->f_dentry, datasync);
|
||||||
} /* vn_fsync() */
|
} /* vn_fsync() */
|
||||||
EXPORT_SYMBOL(vn_fsync);
|
EXPORT_SYMBOL(vn_fsync);
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ splat_atomic_work(void *priv)
|
|||||||
(long unsigned)ap->ap_atomic,
|
(long unsigned)ap->ap_atomic,
|
||||||
(long unsigned)ap->ap_atomic_exited);
|
(long unsigned)ap->ap_atomic_exited);
|
||||||
|
|
||||||
thread_exit();
|
|
||||||
wake_up(&ap->ap_waitq);
|
wake_up(&ap->ap_waitq);
|
||||||
|
thread_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -287,7 +287,7 @@ splat_vnode_test6(struct file *file, void *arg)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE,
|
if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE,
|
||||||
FWRITE | FREAD | FCREAT | FEXCL, 0644, &vp, 0, 0))) {
|
FWRITE | FCREAT | FEXCL, 0644, &vp, 0, 0))) {
|
||||||
splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
|
splat_vprint(file, SPLAT_VNODE_TEST6_NAME,
|
||||||
"Failed to vn_open test file: %s (%d)\n",
|
"Failed to vn_open test file: %s (%d)\n",
|
||||||
SPLAT_VNODE_TEST_FILE_RW, rc);
|
SPLAT_VNODE_TEST_FILE_RW, rc);
|
||||||
|
Loading…
Reference in New Issue
Block a user