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;
 }
 
-

Reply via email to