patch-2.1.127 linux/fs/hfs/dir.c
Next file: linux/fs/hfs/dir_cap.c
Previous file: linux/fs/hfs/catalog.c
Back to the patch index
Back to the overall index
- Lines: 335
- Date:
Mon Nov 2 09:35:16 1998
- Orig file:
v2.1.126/linux/fs/hfs/dir.c
- Orig date:
Tue Mar 17 22:18:15 1998
diff -u --recursive --new-file v2.1.126/linux/fs/hfs/dir.c linux/fs/hfs/dir.c
@@ -41,7 +41,8 @@
/* check against reserved names */
reserved = HFS_SB(dir->i_sb)->s_reserved1;
while (reserved->Len) {
- if (hfs_streq(reserved, &cname)) {
+ if (hfs_streq(reserved->Name, reserved->Len,
+ cname.Name, cname.Len)) {
return 1;
}
++reserved;
@@ -51,7 +52,8 @@
if (HFS_I(dir)->entry->cnid == htonl(HFS_ROOT_CNID)) {
reserved = HFS_SB(dir->i_sb)->s_reserved2;
while (reserved->Len) {
- if (hfs_streq(reserved, &cname)) {
+ if (hfs_streq(reserved->Name, reserved->Len,
+ cname.Name, cname.Len)) {
return 1;
}
++reserved;
@@ -129,16 +131,23 @@
*
* Update inodes associated with a deleted entry to reflect its deletion.
* Well, we really just drop the dentry.
+ *
+ * XXX: we should be using delete_inode for some of this stuff.
*/
static inline void mark_inodes_deleted(struct hfs_cat_entry *entry,
struct dentry *dentry)
{
struct dentry *de;
+ struct inode *tmp;
int i;
for (i = 0; i < 4; ++i) {
if ((de = entry->sys_entry[i]) && (dentry != de)) {
dget(de);
+ tmp = de->d_inode;
+ tmp->i_nlink = 0;
+ tmp->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(tmp);
d_delete(de);
dput(de);
}
@@ -177,32 +186,32 @@
int error;
/* build the key, checking against reserved names */
- if (build_key(&key, dir, dentry->d_name.name, dentry->d_name.len)) {
- error = -EEXIST;
- } else {
- /* try to create the file */
- error = hfs_cat_create(entry, &key,
- (mode & S_IWUSR) ? 0 : HFS_FIL_LOCK,
- HFS_SB(dir->i_sb)->s_type,
- HFS_SB(dir->i_sb)->s_creator, &new);
- }
-
- if (!error) {
- update_dirs_plus(entry, 0);
-
- /* create an inode for the new file */
- inode = hfs_iget(new, HFS_I(dir)->file_type, dentry);
- if (!inode) {
- /* XXX correct error? */
- error = -EIO;
- } else {
- if (HFS_I(dir)->d_drop_op)
- HFS_I(dir)->d_drop_op(dentry, HFS_I(dir)->file_type);
- d_instantiate(dentry, inode);
- }
- }
+ if (build_key(&key, dir, dentry->d_name.name, dentry->d_name.len))
+ return -EEXIST;
- return error;
+ if ((error = hfs_cat_create(entry, &key,
+ (mode & S_IWUSR) ? 0 : HFS_FIL_LOCK,
+ HFS_SB(dir->i_sb)->s_type,
+ HFS_SB(dir->i_sb)->s_creator, &new)))
+ return error;
+
+ /* create an inode for the new file. back out if we run
+ * into trouble. */
+ new->count++; /* hfs_iget() eats one */
+ if (!(inode = hfs_iget(new, HFS_I(dir)->file_type, dentry))) {
+ hfs_cat_delete(entry, new, 1);
+ hfs_cat_put(new);
+ return -EIO;
+ }
+
+ hfs_cat_put(new);
+ update_dirs_plus(entry, 0);
+ /* toss any relevant negative dentries */
+ if (HFS_I(dir)->d_drop_op)
+ HFS_I(dir)->d_drop_op(dentry, HFS_I(dir)->file_type);
+ mark_inode_dirty(inode);
+ d_instantiate(dentry, inode);
+ return 0;
}
/*
@@ -223,23 +232,26 @@
/* build the key, checking against reserved names */
if (build_key(&key, parent, dentry->d_name.name,
- dentry->d_name.len)) {
- error = -EEXIST;
- } else {
- /* try to create the directory */
- error = hfs_cat_mkdir(entry, &key, &new);
- }
-
- if (!error) {
- update_dirs_plus(entry, 1);
- inode = hfs_iget(new, HFS_I(parent)->file_type, dentry);
- if (!inode) {
- error = -EIO;
- } else
- d_instantiate(dentry, inode);
- }
+ dentry->d_name.len))
+ return -EEXIST;
- return error;
+ /* try to create the directory */
+ if ((error = hfs_cat_mkdir(entry, &key, &new)))
+ return error;
+
+ /* back out if we run into trouble */
+ new->count++; /* hfs_iget eats one */
+ if (!(inode = hfs_iget(new, HFS_I(parent)->file_type, dentry))) {
+ hfs_cat_delete(entry, new, 1);
+ hfs_cat_put(new);
+ return -EIO;
+ }
+
+ hfs_cat_put(new);
+ update_dirs_plus(entry, 1);
+ mark_inode_dirty(inode);
+ d_instantiate(dentry, inode);
+ return 0;
}
/*
@@ -257,16 +269,14 @@
*/
int hfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
{
- int error;
+ if (!dir)
+ return -ENOENT;
- if (!dir) {
- error = -ENOENT;
- } else if (S_ISREG(mode)) {
- error = hfs_create(dir, dentry, mode);
- } else {
- error = -EPERM;
- }
- return error;
+ /* the only thing we currently do. */
+ if (S_ISREG(mode))
+ return hfs_create(dir, dentry, mode);
+
+ return -EPERM;
}
/*
@@ -285,18 +295,28 @@
int error;
if (build_key(&key, dir, dentry->d_name.name,
- dentry->d_name.len)) {
- error = -EPERM;
- } else if (!(victim = hfs_cat_get(entry->mdb, &key))) {
- error = -ENOENT;
- } else if (victim->type != HFS_CDR_FIL) {
- error = -EPERM;
- } else if (!(error = hfs_cat_delete(entry, victim, 1))) {
+ dentry->d_name.len))
+ return -EPERM;
+
+ if (!(victim = hfs_cat_get(entry->mdb, &key)))
+ return -ENOENT;
+
+ error = -EPERM;
+ if (victim->type != HFS_CDR_FIL)
+ goto hfs_unlink_put;
+
+ if (!(error = hfs_cat_delete(entry, victim, 1))) {
+ struct inode *inode = dentry->d_inode;
+
mark_inodes_deleted(victim, dentry);
+ inode->i_nlink--;
+ inode->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(inode);
d_delete(dentry);
update_dirs_minus(entry, 0);
}
+hfs_unlink_put:
hfs_cat_put(victim); /* Note that hfs_cat_put(NULL) is safe. */
return error;
}
@@ -313,31 +333,50 @@
{
struct hfs_cat_entry *entry = HFS_I(parent)->entry;
struct hfs_cat_entry *victim = NULL;
+ struct inode *inode = dentry->d_inode;
struct hfs_cat_key key;
int error;
+ if (parent == inode) /* can't delete . */
+ return -EPERM;
+
if (build_key(&key, parent, dentry->d_name.name,
- dentry->d_name.len)) {
- error = -EPERM;
- } else if (!(victim = hfs_cat_get(entry->mdb, &key))) {
- error = -ENOENT;
- } else if (victim->type != HFS_CDR_DIR) {
- error = -ENOTDIR;
- } else if (/* we only have to worry about 2 and 3 for mount points */
- (victim->sys_entry[2] &&
- (victim->sys_entry[2] !=
- victim->sys_entry[2]->d_mounts)) ||
- (victim->sys_entry[3] &&
- (victim->sys_entry[3] !=
- victim->sys_entry[3]->d_mounts))
- ) {
- error = -EBUSY;
- } else if (!(error = hfs_cat_delete(entry, victim, 1))) {
- mark_inodes_deleted(victim, dentry);
- d_delete(dentry);
- update_dirs_minus(entry, 1);
- }
+ dentry->d_name.len))
+ return -EPERM;
+
+ if (!(victim = hfs_cat_get(entry->mdb, &key)))
+ return -ENOENT;
+
+ error = -ENOTDIR;
+ if (victim->type != HFS_CDR_DIR)
+ goto hfs_rmdir_put;
+
+ error = -EBUSY;
+ if (dentry->d_count > 1)
+ goto hfs_rmdir_put;
+
+ if (/* we only have to worry about 2 and 3 for mount points */
+ (victim->sys_entry[2] &&
+ (victim->sys_entry[2]->d_mounts !=
+ victim->sys_entry[2]->d_covers)) ||
+ (victim->sys_entry[3] &&
+ (victim->sys_entry[3]->d_mounts !=
+ victim->sys_entry[3]->d_covers))
+ )
+ goto hfs_rmdir_put;
+
+
+ if ((error = hfs_cat_delete(entry, victim, 1)))
+ goto hfs_rmdir_put;
+
+ mark_inodes_deleted(victim, dentry);
+ inode->i_nlink = 0;
+ inode->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+ d_delete(dentry);
+ update_dirs_minus(entry, 1);
+hfs_rmdir_put:
hfs_cat_put(victim); /* Note that hfs_cat_put(NULL) is safe. */
return error;
}
@@ -365,35 +404,40 @@
if (build_key(&key, old_dir, old_dentry->d_name.name,
old_dentry->d_name.len) ||
- (HFS_ITYPE(old_dir->i_ino) != HFS_ITYPE(new_dir->i_ino))) {
- error = -EPERM;
- } else if (!(victim = hfs_cat_get(old_parent->mdb, &key))) {
- error = -ENOENT;
- } else if (build_key(&key, new_dir, new_dentry->d_name.name,
- new_dentry->d_name.len)) {
- error = -EPERM;
- } else if (!(error = hfs_cat_move(old_parent, new_parent,
- victim, &key, &deleted))) {
- int is_dir = (victim->type == HFS_CDR_DIR);
+ (HFS_ITYPE(old_dir->i_ino) != HFS_ITYPE(new_dir->i_ino)))
+ return -EPERM;
+ if (!(victim = hfs_cat_get(old_parent->mdb, &key)))
+ return -ENOENT;
+
+ error = -EPERM;
+ if (build_key(&key, new_dir, new_dentry->d_name.name,
+ new_dentry->d_name.len))
+ goto hfs_rename_put;
+
+ if (!(error = hfs_cat_move(old_parent, new_parent,
+ victim, &key, &deleted))) {
+ int is_dir = (victim->type == HFS_CDR_DIR);
+
/* drop the old dentries */
mark_inodes_deleted(victim, old_dentry);
update_dirs_minus(old_parent, is_dir);
if (deleted) {
- mark_inodes_deleted(deleted, new_dentry);
- hfs_cat_put(deleted);
+ mark_inodes_deleted(deleted, new_dentry);
+ hfs_cat_put(deleted);
} else {
- /* no existing inodes. just drop negative dentries */
- if (HFS_I(new_dir)->d_drop_op)
- HFS_I(new_dir)->d_drop_op(new_dentry,
- HFS_I(new_dir)->file_type);
- update_dirs_plus(new_parent, is_dir);
+ /* no existing inodes. just drop negative dentries */
+ if (HFS_I(new_dir)->d_drop_op)
+ HFS_I(new_dir)->d_drop_op(new_dentry,
+ HFS_I(new_dir)->file_type);
+ update_dirs_plus(new_parent, is_dir);
}
-
+
/* update dcache */
d_move(old_dentry, new_dentry);
}
+hfs_rename_put:
hfs_cat_put(victim); /* Note that hfs_cat_put(NULL) is safe. */
return error;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov