Module Name:    src
Committed By:   reinoud
Date:           Sun Jul  7 19:49:44 UTC 2013

Modified Files:
        src/sys/fs/udf: udf_subr.c udf_subr.h udf_vnops.c

Log Message:
Implement a real empty-directory checking for rmdir().

Should should fix the other part of PR kern/47987
Solves tests/vfs/t_vnops udf_dir_notempty


To generate a diff of this commit:
cvs rdiff -u -r1.119 -r1.120 src/sys/fs/udf/udf_subr.c
cvs rdiff -u -r1.18 -r1.19 src/sys/fs/udf/udf_subr.h
cvs rdiff -u -r1.81 -r1.82 src/sys/fs/udf/udf_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/udf/udf_subr.c
diff -u src/sys/fs/udf/udf_subr.c:1.119 src/sys/fs/udf/udf_subr.c:1.120
--- src/sys/fs/udf/udf_subr.c:1.119	Sun Apr 29 22:53:59 2012
+++ src/sys/fs/udf/udf_subr.c	Sun Jul  7 19:49:44 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_subr.c,v 1.119 2012/04/29 22:53:59 chs Exp $ */
+/* $NetBSD: udf_subr.c,v 1.120 2013/07/07 19:49:44 reinoud Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.119 2012/04/29 22:53:59 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.120 2013/07/07 19:49:44 reinoud Exp $");
 #endif /* not lint */
 
 
@@ -4458,8 +4458,8 @@ udf_setownership(struct udf_node *udf_no
 /* --------------------------------------------------------------------- */
 
 
-static int
-dirhash_fill(struct udf_node *dir_node)
+int
+udf_dirhash_fill(struct udf_node *dir_node)
 {
 	struct vnode *dvp = dir_node->vnode;
 	struct dirhash *dirh;
@@ -4556,7 +4556,7 @@ udf_lookup_name_in_dir(struct vnode *vp,
 
 	/* get our dirhash and make sure its read in */
 	dirhash_get(&dir_node->dir_hash);
-	error = dirhash_fill(dir_node);
+	error = udf_dirhash_fill(dir_node);
 	if (error) {
 		dirhash_put(dir_node->dir_hash);
 		return error;
@@ -4789,7 +4789,7 @@ udf_dir_detach(struct udf_mount *ump, st
 
 	/* get our dirhash and make sure its read in */
 	dirhash_get(&dir_node->dir_hash);
-	error = dirhash_fill(dir_node);
+	error = udf_dirhash_fill(dir_node);
 	if (error) {
 		dirhash_put(dir_node->dir_hash);
 		return error;
@@ -4938,7 +4938,7 @@ udf_dir_update_rootentry(struct udf_moun
 
 	/* get our dirhash and make sure its read in */
 	dirhash_get(&dir_node->dir_hash);
-	error = dirhash_fill(dir_node);
+	error = udf_dirhash_fill(dir_node);
 	if (error) {
 		dirhash_put(dir_node->dir_hash);
 		return error;
@@ -5061,7 +5061,7 @@ udf_dir_attach(struct udf_mount *ump, st
 
 	/* get our dirhash and make sure its read in */
 	dirhash_get(&dir_node->dir_hash);
-	error = dirhash_fill(dir_node);
+	error = udf_dirhash_fill(dir_node);
 	if (error) {
 		dirhash_put(dir_node->dir_hash);
 		return error;

Index: src/sys/fs/udf/udf_subr.h
diff -u src/sys/fs/udf/udf_subr.h:1.18 src/sys/fs/udf/udf_subr.h:1.19
--- src/sys/fs/udf/udf_subr.h:1.18	Thu Feb 25 16:15:58 2010
+++ src/sys/fs/udf/udf_subr.h	Sun Jul  7 19:49:44 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_subr.h,v 1.18 2010/02/25 16:15:58 reinoud Exp $ */
+/* $NetBSD: udf_subr.h,v 1.19 2013/07/07 19:49:44 reinoud Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -170,9 +170,11 @@ int udf_create_node(struct vnode *dvp, s
 void udf_delete_node(struct udf_node *udf_node);
 
 int udf_chsize(struct vnode *vp, u_quad_t newsize, kauth_cred_t cred);
+
 int udf_dir_detach(struct udf_mount *ump, struct udf_node *dir_node, struct udf_node *udf_node, struct componentname *cnp);
 int udf_dir_attach(struct udf_mount *ump, struct udf_node *dir_node, struct udf_node *udf_node, struct vattr *vap, struct componentname *cnp);
 int udf_dir_update_rootentry(struct udf_mount *ump, struct udf_node *dir_node, struct udf_node *new_parent_node);
+int udf_dirhash_fill(struct udf_node *dir_node);
 
 /* update and times */
 void udf_add_to_dirtylist(struct udf_node *udf_node);

Index: src/sys/fs/udf/udf_vnops.c
diff -u src/sys/fs/udf/udf_vnops.c:1.81 src/sys/fs/udf/udf_vnops.c:1.82
--- src/sys/fs/udf/udf_vnops.c:1.81	Fri Jul  5 20:40:20 2013
+++ src/sys/fs/udf/udf_vnops.c	Sun Jul  7 19:49:44 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vnops.c,v 1.81 2013/07/05 20:40:20 reinoud Exp $ */
+/* $NetBSD: udf_vnops.c,v 1.82 2013/07/07 19:49:44 reinoud Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.81 2013/07/05 20:40:20 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.82 2013/07/07 19:49:44 reinoud Exp $");
 #endif /* not lint */
 
 
@@ -2191,7 +2191,7 @@ udf_rmdir(void *v)
 	struct udf_node *dir_node = VTOI(dvp);
 	struct udf_node *udf_node = VTOI(vp);
 	struct udf_mount *ump = dir_node->ump;
-	int refcnt, error;
+	int error, isempty;
 
 	DPRINTF(NOTIMPL, ("udf_rmdir '%s' called\n", cnp->cn_nameptr));
 
@@ -2202,15 +2202,19 @@ udf_rmdir(void *v)
 		return EINVAL;
 	}
 
-	/* check to see if the directory is empty */
-	error = 0;
-	if (dir_node->fe) {
-		refcnt = udf_rw16(udf_node->fe->link_cnt);
-	} else {
-		refcnt = udf_rw16(udf_node->efe->link_cnt);
+	/* make sure our `leaf' node's hash is populated */
+	dirhash_get(&udf_node->dir_hash);
+	error = udf_dirhash_fill(udf_node);
+	if (error) {
+		dirhash_put(udf_node->dir_hash);
+		return error;
 	}
-	if (refcnt > 1) {
-		/* NOT empty */
+
+	/* check to see if the directory is empty */
+	isempty = dirhash_dir_isempty(udf_node->dir_hash);
+	dirhash_put(udf_node->dir_hash);
+
+	if (!isempty) {
 		vput(dvp);
 		vput(vp);
 		return ENOTEMPTY;

Reply via email to