1 |
/* libdiskfs implementation of fs.defs: dir_unlink |
/* libdiskfs implementation of fs.defs: dir_unlink |
2 |
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 Free Software Foundation |
Copyright (C) 1992,93,94,95,96,97,2002 Free Software Foundation, Inc. |
3 |
|
|
4 |
This program is free software; you can redistribute it and/or |
This program is free software; you can redistribute it and/or |
5 |
modify it under the terms of the GNU General Public License as |
modify it under the terms of the GNU General Public License as |
32 |
|
|
33 |
if (!dircred) |
if (!dircred) |
34 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
35 |
|
|
36 |
dnp = dircred->po->np; |
dnp = dircred->po->np; |
37 |
if (diskfs_check_readonly ()) |
if (diskfs_check_readonly ()) |
38 |
return EROFS; |
return EROFS; |
41 |
|
|
42 |
error = diskfs_lookup (dnp, name, REMOVE, &np, ds, dircred); |
error = diskfs_lookup (dnp, name, REMOVE, &np, ds, dircred); |
43 |
if (error == EAGAIN) |
if (error == EAGAIN) |
44 |
error = EISDIR; |
error = EPERM; /* 1003.1-1996 5.5.1.4 */ |
45 |
if (error) |
if (error) |
46 |
{ |
{ |
47 |
diskfs_drop_dirstat (dnp, ds); |
diskfs_drop_dirstat (dnp, ds); |
48 |
mutex_unlock (&dnp->lock); |
mutex_unlock (&dnp->lock); |
49 |
return error; |
return error; |
50 |
} |
} |
51 |
|
|
52 |
/* This isn't the BSD behavior, but it is Posix compliant and saves |
/* This isn't the BSD behavior, but it is Posix compliant and saves |
53 |
us on several race conditions.*/ |
us on several race conditions.*/ |
54 |
if (S_ISDIR(np->dn_stat.st_mode)) |
if (S_ISDIR(np->dn_stat.st_mode)) |
59 |
diskfs_nput (np); |
diskfs_nput (np); |
60 |
diskfs_drop_dirstat (dnp, ds); |
diskfs_drop_dirstat (dnp, ds); |
61 |
mutex_unlock (&dnp->lock); |
mutex_unlock (&dnp->lock); |
62 |
return EISDIR; |
return EPERM; /* 1003.1-1996 5.5.1.4 */ |
63 |
} |
} |
64 |
|
|
65 |
error = diskfs_dirremove (dnp, np, name, ds); |
error = diskfs_dirremove (dnp, np, name, ds); |
66 |
if (diskfs_synchronous) |
if (diskfs_synchronous) |
67 |
diskfs_node_update (dnp, 1); |
diskfs_node_update (dnp, 1); |
71 |
mutex_unlock (&dnp->lock); |
mutex_unlock (&dnp->lock); |
72 |
return error; |
return error; |
73 |
} |
} |
74 |
|
|
75 |
np->dn_stat.st_nlink--; |
np->dn_stat.st_nlink--; |
76 |
np->dn_set_ctime = 1; |
np->dn_set_ctime = 1; |
77 |
if (diskfs_synchronous) |
if (diskfs_synchronous) |
80 |
if (np->dn_stat.st_nlink == 0) |
if (np->dn_stat.st_nlink == 0) |
81 |
fshelp_fetch_control (&np->transbox, &control); |
fshelp_fetch_control (&np->transbox, &control); |
82 |
|
|
83 |
/* This check is necessary because we might get here on an error while |
/* This check is necessary because we might get here on an error while |
84 |
checking the mode on something which happens to be `.'. */ |
checking the mode on something which happens to be `.'. */ |
85 |
if (np == dnp) |
if (np == dnp) |
86 |
diskfs_nrele (np); |
diskfs_nrele (np); |
87 |
else |
else |
88 |
diskfs_nput (np); |
diskfs_nput (np); |
89 |
mutex_unlock (&dnp->lock); |
mutex_unlock (&dnp->lock); |