v7fs_lookup() fix return value. Pass t_vnops rename_dir(3)
v7fs_setttr() check credential. Pass t_unpriv owner v7fs_rename() reload inode(v7fs_vnode_reload). Pass t_vnops rename_reg_nodir
This commit is contained in:
parent
53172ceae2
commit
b53b51d13e
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: v7fs_vfsops.c,v 1.3 2011/07/23 05:10:30 uch Exp $ */
|
/* $NetBSD: v7fs_vfsops.c,v 1.4 2011/07/30 03:53:18 uch Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2004, 2011 The NetBSD Foundation, Inc.
|
* Copyright (c) 2004, 2011 The NetBSD Foundation, Inc.
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: v7fs_vfsops.c,v 1.3 2011/07/23 05:10:30 uch Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: v7fs_vfsops.c,v 1.4 2011/07/30 03:53:18 uch Exp $");
|
||||||
#if defined _KERNEL_OPT
|
#if defined _KERNEL_OPT
|
||||||
#include "opt_v7fs.h"
|
#include "opt_v7fs.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,6 +75,7 @@ static int v7fs_openfs(struct vnode *, struct mount *, struct lwp *);
|
||||||
static void v7fs_closefs(struct vnode *, struct mount *);
|
static void v7fs_closefs(struct vnode *, struct mount *);
|
||||||
static int is_v7fs_partition(struct vnode *);
|
static int is_v7fs_partition(struct vnode *);
|
||||||
static enum vtype v7fs_mode_to_vtype(v7fs_mode_t mode);
|
static enum vtype v7fs_mode_to_vtype(v7fs_mode_t mode);
|
||||||
|
int v7fs_vnode_reload(struct mount *, struct vnode *);
|
||||||
|
|
||||||
int
|
int
|
||||||
v7fs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
|
v7fs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
|
||||||
|
@ -594,3 +595,34 @@ v7fs_mountroot(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reload disk inode information */
|
||||||
|
int
|
||||||
|
v7fs_vnode_reload(struct mount *mp, struct vnode *vp)
|
||||||
|
{
|
||||||
|
struct v7fs_mount *v7fsmount = mp->mnt_data;
|
||||||
|
struct v7fs_self *fs = v7fsmount->core;
|
||||||
|
struct v7fs_node *v7fs_node;
|
||||||
|
struct v7fs_inode *inode = &((struct v7fs_node *)vp->v_data)->inode;
|
||||||
|
int target_ino = inode->inode_number;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
DPRINTF("#%d\n", target_ino);
|
||||||
|
mutex_enter(&mntvnode_lock);
|
||||||
|
for (v7fs_node = LIST_FIRST(&v7fsmount->v7fs_node_head);
|
||||||
|
v7fs_node != NULL; v7fs_node = LIST_NEXT(v7fs_node, link)) {
|
||||||
|
inode = &v7fs_node->inode;
|
||||||
|
if (!v7fs_inode_allocated(inode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (inode->inode_number == target_ino) {
|
||||||
|
error = v7fs_inode_load(fs, &v7fs_node->inode,
|
||||||
|
target_ino);
|
||||||
|
DPRINTF("sync #%d error=%d\n", target_ino, error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_exit(&mntvnode_lock);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: v7fs_vnops.c,v 1.5 2011/07/24 12:31:33 uch Exp $ */
|
/* $NetBSD: v7fs_vnops.c,v 1.6 2011/07/30 03:53:18 uch Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2004, 2011 The NetBSD Foundation, Inc.
|
* Copyright (c) 2004, 2011 The NetBSD Foundation, Inc.
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.5 2011/07/24 12:31:33 uch Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.6 2011/07/30 03:53:18 uch Exp $");
|
||||||
#if defined _KERNEL_OPT
|
#if defined _KERNEL_OPT
|
||||||
#include "opt_v7fs.h"
|
#include "opt_v7fs.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,6 +67,8 @@ __KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.5 2011/07/24 12:31:33 uch Exp $");
|
||||||
MALLOC_JUSTDEFINE(M_V7FS_VNODE, "v7fs vnode", "v7fs vnode structures");
|
MALLOC_JUSTDEFINE(M_V7FS_VNODE, "v7fs vnode", "v7fs vnode structures");
|
||||||
MALLOC_DECLARE(M_V7FS);
|
MALLOC_DECLARE(M_V7FS);
|
||||||
|
|
||||||
|
int v7fs_vnode_reload(struct mount *, struct vnode *);
|
||||||
|
|
||||||
static v7fs_mode_t vtype_to_v7fs_mode(enum vtype);
|
static v7fs_mode_t vtype_to_v7fs_mode(enum vtype);
|
||||||
static uint8_t v7fs_mode_to_d_type(v7fs_mode_t);
|
static uint8_t v7fs_mode_to_d_type(v7fs_mode_t);
|
||||||
|
|
||||||
|
@ -110,9 +112,11 @@ v7fs_lookup(void *v)
|
||||||
bool islastcn = flags & ISLASTCN;
|
bool islastcn = flags & ISLASTCN;
|
||||||
v7fs_ino_t ino;
|
v7fs_ino_t ino;
|
||||||
int error;
|
int error;
|
||||||
|
#ifdef V7FS_VNOPS_DEBUG
|
||||||
DPRINTF("%s op=%d flags=%d parent=%d %o %dbyte\n", name,
|
const char *opname[] = { "LOOKUP", "CREATE", "DELETE", "RENAME" };
|
||||||
nameiop, cnp->cn_flags, parent->inode_number, parent->mode,
|
#endif
|
||||||
|
DPRINTF("'%s' op=%s flags=%d parent=%d %o %dbyte\n", name,
|
||||||
|
opname[nameiop], cnp->cn_flags, parent->inode_number, parent->mode,
|
||||||
parent->filesize);
|
parent->filesize);
|
||||||
|
|
||||||
*a->a_vpp = 0;
|
*a->a_vpp = 0;
|
||||||
|
@ -132,6 +136,9 @@ v7fs_lookup(void *v)
|
||||||
|
|
||||||
/* "." */
|
/* "." */
|
||||||
if (namelen == 1 && name[0] == '.') {
|
if (namelen == 1 && name[0] == '.') {
|
||||||
|
if ((nameiop == RENAME) && islastcn) {
|
||||||
|
return EISDIR; /* t_vnops rename_dir(3) */
|
||||||
|
}
|
||||||
vref(dvp); /* v_usecount++ */
|
vref(dvp); /* v_usecount++ */
|
||||||
*a->a_vpp = dvp;
|
*a->a_vpp = dvp;
|
||||||
DPRINTF("done.(.)\n");
|
DPRINTF("done.(.)\n");
|
||||||
|
@ -170,7 +177,7 @@ v7fs_lookup(void *v)
|
||||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
}
|
}
|
||||||
*a->a_vpp = vpp;
|
*a->a_vpp = vpp;
|
||||||
DPRINTF("done.\n");
|
DPRINTF("done.(%s)\n", name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -439,6 +446,7 @@ v7fs_setattr(void *v)
|
||||||
struct v7fs_node *v7node = vp->v_data;
|
struct v7fs_node *v7node = vp->v_data;
|
||||||
struct v7fs_self *fs = v7node->v7fsmount->core;
|
struct v7fs_self *fs = v7node->v7fsmount->core;
|
||||||
struct v7fs_inode *inode = &v7node->inode;
|
struct v7fs_inode *inode = &v7node->inode;
|
||||||
|
kauth_cred_t cred = ap->a_cred;
|
||||||
struct timespec *acc, *mod;
|
struct timespec *acc, *mod;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
acc = mod = NULL;
|
acc = mod = NULL;
|
||||||
|
@ -477,15 +485,38 @@ v7fs_setattr(void *v)
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
uvm_vnp_setsize(vp, vap->va_size);
|
uvm_vnp_setsize(vp, vap->va_size);
|
||||||
}
|
}
|
||||||
|
uid_t uid = inode->uid;
|
||||||
|
gid_t gid = inode->gid;
|
||||||
|
|
||||||
if (vap->va_uid != (uid_t)VNOVAL) {
|
if (vap->va_uid != (uid_t)VNOVAL) {
|
||||||
inode->uid = vap->va_uid;
|
uid = vap->va_uid;
|
||||||
|
error = kauth_authorize_vnode(cred,
|
||||||
|
KAUTH_VNODE_CHANGE_OWNERSHIP, vp, NULL,
|
||||||
|
genfs_can_chown(vp, cred, inode->uid, inode->gid, uid,
|
||||||
|
gid));
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
inode->uid = uid;
|
||||||
}
|
}
|
||||||
if (vap->va_gid != (uid_t)VNOVAL) {
|
if (vap->va_gid != (uid_t)VNOVAL) {
|
||||||
inode->gid = vap->va_gid;
|
gid = vap->va_gid;
|
||||||
|
error = kauth_authorize_vnode(cred,
|
||||||
|
KAUTH_VNODE_CHANGE_OWNERSHIP, vp, NULL,
|
||||||
|
genfs_can_chown(vp, cred, inode->uid, inode->gid, uid,
|
||||||
|
gid));
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
inode->gid = gid;
|
||||||
}
|
}
|
||||||
if (vap->va_mode != (mode_t)VNOVAL) {
|
if (vap->va_mode != (mode_t)VNOVAL) {
|
||||||
v7fs_inode_chmod(inode, vap->va_mode);
|
mode_t mode = vap->va_mode;
|
||||||
|
error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_SECURITY,
|
||||||
|
vp, NULL, genfs_can_chmod(vp, cred, inode->uid, inode->gid,
|
||||||
|
mode));
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
v7fs_inode_chmod(inode, mode);
|
||||||
}
|
}
|
||||||
if (vap->va_atime.tv_sec != VNOVAL) {
|
if (vap->va_atime.tv_sec != VNOVAL) {
|
||||||
acc = &vap->va_atime;
|
acc = &vap->va_atime;
|
||||||
|
@ -725,8 +756,8 @@ v7fs_rename(void *v)
|
||||||
const char *to_name = a->a_tcnp->cn_nameptr;
|
const char *to_name = a->a_tcnp->cn_nameptr;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
DPRINTF("%s->%s\n", from_name, to_name);
|
DPRINTF("%s->%s %p %p\n", from_name, to_name, fvp, tvp);
|
||||||
/* tvp may be NULL. allocated here. */
|
|
||||||
if ((fvp->v_mount != tdvp->v_mount) ||
|
if ((fvp->v_mount != tdvp->v_mount) ||
|
||||||
(tvp && (fvp->v_mount != tvp->v_mount))) {
|
(tvp && (fvp->v_mount != tvp->v_mount))) {
|
||||||
error = EXDEV;
|
error = EXDEV;
|
||||||
|
@ -736,6 +767,11 @@ v7fs_rename(void *v)
|
||||||
// XXXsource file lock?
|
// XXXsource file lock?
|
||||||
error = v7fs_file_rename(fs, &parent_from->inode, from_name,
|
error = v7fs_file_rename(fs, &parent_from->inode, from_name,
|
||||||
&parent_to->inode, to_name);
|
&parent_to->inode, to_name);
|
||||||
|
/* 'to file' inode may be changed. (hard-linked and it is cached.)
|
||||||
|
t_vnops rename_reg_nodir */
|
||||||
|
if (tvp) {
|
||||||
|
v7fs_vnode_reload(parent_from->v7fsmount->mountp, tvp);
|
||||||
|
}
|
||||||
/* Sync dirent size change. */
|
/* Sync dirent size change. */
|
||||||
uvm_vnp_setsize(tdvp, v7fs_inode_filesize(&parent_to->inode));
|
uvm_vnp_setsize(tdvp, v7fs_inode_filesize(&parent_to->inode));
|
||||||
uvm_vnp_setsize(fdvp, v7fs_inode_filesize(&parent_from->inode));
|
uvm_vnp_setsize(fdvp, v7fs_inode_filesize(&parent_from->inode));
|
||||||
|
@ -1272,4 +1308,3 @@ error_exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue