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;