Module Name: src Committed By: uch Date: Sat Jul 30 03:53:18 UTC 2011
Modified Files: src/sys/fs/v7fs: v7fs_vfsops.c v7fs_vnops.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/fs/v7fs/v7fs_vfsops.c cvs rdiff -u -r1.5 -r1.6 src/sys/fs/v7fs/v7fs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/fs/v7fs/v7fs_vfsops.c diff -u src/sys/fs/v7fs/v7fs_vfsops.c:1.3 src/sys/fs/v7fs/v7fs_vfsops.c:1.4 --- src/sys/fs/v7fs/v7fs_vfsops.c:1.3 Sat Jul 23 05:10:30 2011 +++ src/sys/fs/v7fs/v7fs_vfsops.c Sat Jul 30 03:53:18 2011 @@ -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. @@ -30,7 +30,7 @@ */ #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 #include "opt_v7fs.h" #endif @@ -75,6 +75,7 @@ static void v7fs_closefs(struct vnode *, struct mount *); static int is_v7fs_partition(struct vnode *); static enum vtype v7fs_mode_to_vtype(v7fs_mode_t mode); +int v7fs_vnode_reload(struct mount *, struct vnode *); int v7fs_mount(struct mount *mp, const char *path, void *data, size_t *data_len) @@ -594,3 +595,34 @@ 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; +} Index: src/sys/fs/v7fs/v7fs_vnops.c diff -u src/sys/fs/v7fs/v7fs_vnops.c:1.5 src/sys/fs/v7fs/v7fs_vnops.c:1.6 --- src/sys/fs/v7fs/v7fs_vnops.c:1.5 Sun Jul 24 12:31:33 2011 +++ src/sys/fs/v7fs/v7fs_vnops.c Sat Jul 30 03:53:18 2011 @@ -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. @@ -30,7 +30,7 @@ */ #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 #include "opt_v7fs.h" #endif @@ -67,6 +67,8 @@ MALLOC_JUSTDEFINE(M_V7FS_VNODE, "v7fs vnode", "v7fs vnode structures"); MALLOC_DECLARE(M_V7FS); +int v7fs_vnode_reload(struct mount *, struct vnode *); + static v7fs_mode_t vtype_to_v7fs_mode(enum vtype); static uint8_t v7fs_mode_to_d_type(v7fs_mode_t); @@ -110,9 +112,11 @@ bool islastcn = flags & ISLASTCN; v7fs_ino_t ino; int error; - - DPRINTF("%s op=%d flags=%d parent=%d %o %dbyte\n", name, - nameiop, cnp->cn_flags, parent->inode_number, parent->mode, +#ifdef V7FS_VNOPS_DEBUG + const char *opname[] = { "LOOKUP", "CREATE", "DELETE", "RENAME" }; +#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); *a->a_vpp = 0; @@ -132,6 +136,9 @@ /* "." */ if (namelen == 1 && name[0] == '.') { + if ((nameiop == RENAME) && islastcn) { + return EISDIR; /* t_vnops rename_dir(3) */ + } vref(dvp); /* v_usecount++ */ *a->a_vpp = dvp; DPRINTF("done.(.)\n"); @@ -170,7 +177,7 @@ vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); } *a->a_vpp = vpp; - DPRINTF("done.\n"); + DPRINTF("done.(%s)\n", name); return 0; } @@ -439,6 +446,7 @@ struct v7fs_node *v7node = vp->v_data; struct v7fs_self *fs = v7node->v7fsmount->core; struct v7fs_inode *inode = &v7node->inode; + kauth_cred_t cred = ap->a_cred; struct timespec *acc, *mod; int error = 0; acc = mod = NULL; @@ -477,15 +485,38 @@ if (error == 0) uvm_vnp_setsize(vp, vap->va_size); } + uid_t uid = inode->uid; + gid_t gid = inode->gid; 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) { - 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) { - 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) { acc = &vap->va_atime; @@ -725,8 +756,8 @@ const char *to_name = a->a_tcnp->cn_nameptr; int error; - DPRINTF("%s->%s\n", from_name, to_name); - /* tvp may be NULL. allocated here. */ + DPRINTF("%s->%s %p %p\n", from_name, to_name, fvp, tvp); + if ((fvp->v_mount != tdvp->v_mount) || (tvp && (fvp->v_mount != tvp->v_mount))) { error = EXDEV; @@ -736,6 +767,11 @@ // XXXsource file lock? error = v7fs_file_rename(fs, &parent_from->inode, from_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. */ uvm_vnp_setsize(tdvp, v7fs_inode_filesize(&parent_to->inode)); uvm_vnp_setsize(fdvp, v7fs_inode_filesize(&parent_from->inode)); @@ -1272,4 +1308,3 @@ return error; } -