patch-2.1.127 linux/fs/hfs/catalog.c
Next file: linux/fs/hfs/dir.c
Previous file: linux/fs/hfs/bnode.c
Back to the patch index
Back to the overall index
- Lines: 284
- Date:
Mon Nov 2 09:35:16 1998
- Orig file:
v2.1.126/linux/fs/hfs/catalog.c
- Orig date:
Tue Mar 17 22:18:15 1998
diff -u --recursive --new-file v2.1.126/linux/fs/hfs/catalog.c linux/fs/hfs/catalog.c
@@ -127,17 +127,15 @@
*
* hash an (struct mdb *) and a (struct hfs_cat_key *) to an integer.
*/
-static inline unsigned long hashfn(const struct hfs_mdb *mdb,
+static inline unsigned int hashfn(const struct hfs_mdb *mdb,
const struct hfs_cat_key *key)
{
-#define LSB(X) (((unsigned char *)(&X))[3])
- unsigned long hash;
+ unsigned int hash;
- hash = (unsigned long) mdb | (unsigned long) key->ParID[3] |
- hfs_strhash(&key->CName);
+ hash = (unsigned long) mdb | (unsigned long) key->ParID[3] |
+ hfs_strhash(key->CName.Name, key->CName.Len);
hash = hash ^ (hash >> C_HASHBITS) ^ (hash >> C_HASHBITS*2);
return hash & C_HASHMASK;
-#undef LSB
}
/*
@@ -533,7 +531,6 @@
HFS_BKEY(key), HFS_BFIND_READ_EQ)) {
/* uh oh. we failed to read the record.
* the entry doesn't actually exist. */
- entry->state |= HFS_DELETED;
goto read_fail;
}
@@ -564,12 +561,14 @@
return NULL;
read_fail:
- /* spinlock unlocked already. we don't need to mark the entry
- * dirty here because we know that it doesn't exist. */
- remove_hash(entry);
- entry->state &= ~HFS_LOCK;
- hfs_wake_up(&entry->wait);
- hfs_cat_put(entry);
+ /* short-cut hfs_cat_put by doing everything here. */
+ spin_lock(&entry_lock);
+ list_del(&entry->hash);
+ list_del(&entry->list);
+ init_entry(entry);
+ list_add(&entry->list, &entry_unused);
+ entries_stat.nr_free_entries++;
+ spin_unlock(&entry_lock);
return NULL;
}
@@ -586,6 +585,11 @@
{
struct hfs_cat_entry * entry;
+#if defined(DEBUG_CATALOG) || defined(DEBUG_ALL)
+ hfs_warn("hfs_get_entry: mdb=%p key=%s read=%d\n",
+ mdb, key->CName.Name, read);
+#endif
+
spin_lock(&entry_lock);
entry = find_entry(mdb, key);
if (!entry) {
@@ -759,6 +763,7 @@
/* complete the cache entry and return success */
__read_entry(entry, record);
unlock_entry(entry);
+
if (result) {
*result = entry;
} else {
@@ -786,17 +791,7 @@
*
* Release an entry we aren't using anymore.
*
- * NOTE: We must be careful any time we sleep on a non-deleted
- * entry that the entry is in a consistent state, since another
- * process may get the entry while we sleep. That is why we
- * 'goto repeat' after each operation that might sleep.
- *
- * ADDITIONAL NOTE: the sys_entries will remove themselves from
- * the sys_entry list on the final iput, so we don't need
- * to worry about them here.
- *
- * nothing in hfs_cat_put goes to sleep now except
- * on the initial entry.
+ * nothing in hfs_cat_put goes to sleep now except on the initial entry.
*/
void hfs_cat_put(struct hfs_cat_entry * entry)
{
@@ -810,9 +805,13 @@
return;
}
+#if defined(DEBUG_CATALOG) || defined(DEBUG_ALL)
+ hfs_warn("hfs_cat_put: %p(%u) type=%d state=%lu\n",
+ entry, entry->count, entry->type, entry->state);
+#endif
spin_lock(&entry_lock);
if (!--entry->count) {
- if ((entry->state & HFS_DELETED))
+ if ((entry->state & HFS_DELETED))
goto entry_deleted;
if ((entry->type == HFS_CDR_FIL)) {
@@ -840,10 +839,7 @@
HFS_DELETE(entry);
entries_stat.nr_entries--;
} else {
- spin_unlock(&entry_lock);
- wait_on_entry(entry);
init_entry(entry);
- spin_lock(&entry_lock);
list_add(&entry->list, &entry_unused);
entries_stat.nr_free_entries++;
}
@@ -919,7 +915,7 @@
* hfs_cat_invalidate()
*
* Called by hfs_mdb_put() to remove all the entries
- * in the cache which are associated with a given MDB.
+ * in the cache that are associated with a given MDB.
*/
void hfs_cat_invalidate(struct hfs_mdb *mdb)
{
@@ -931,6 +927,11 @@
spin_unlock(&entry_lock);
delete_list(&throw_away);
+#if defined(DEBUG_CATALOG) || defined(DEBUG_ALL)
+ hfs_warn("hfs_cat_invalidate: free=%d total=%d\n",
+ entries_stat.nr_free_entries,
+ entries_stat.nr_entries);
+#endif
}
/*
@@ -941,7 +942,7 @@
void hfs_cat_commit(struct hfs_mdb *mdb)
{
struct list_head *tmp, *head = &mdb->entry_dirty;
- struct hfs_cat_entry * entry;
+ struct hfs_cat_entry *entry;
spin_lock(&entry_lock);
while ((tmp = head->prev) != head) {
@@ -1018,7 +1019,8 @@
if (parents != 0) {
retval = (int)parents;
} else {
- retval = hfs_strcmp(&key1->CName, &key2->CName);
+ retval = hfs_strcmp(key1->CName.Name, key1->CName.Len,
+ key2->CName.Name, key2->CName.Len);
}
return retval;
}
@@ -1170,9 +1172,6 @@
* Create a new file with the indicated name in the indicated directory.
* The file will have the indicated flags, type and creator.
* If successful an (struct hfs_cat_entry) is returned in '*result'.
- *
- * XXX: the presence of "record" probably means that the following two
- * aren't currently SMP safe and need spinlocks.
*/
int hfs_cat_create(struct hfs_cat_entry *parent, struct hfs_cat_key *key,
hfs_u8 flags, hfs_u32 type, hfs_u32 creator,
@@ -1182,6 +1181,10 @@
hfs_u32 id = new_cnid(parent->mdb);
hfs_u32 mtime = hfs_time();
+#if defined(DEBUG_CATALOG) || defined(DEBUG_ALL)
+ hfs_warn("hfs_cat_create: %p/%s flags=%d res=%p\n",
+ parent, key->CName.Name, flags, result);
+#endif
/* init some fields for the file record */
memset(&record, 0, sizeof(record));
record.cdrType = HFS_CDR_FIL;
@@ -1209,6 +1212,11 @@
hfs_u32 id = new_cnid(parent->mdb);
hfs_u32 mtime = hfs_time();
+#if defined(DEBUG_CATALOG) || defined(DEBUG_ALL)
+ hfs_warn("hfs_cat_mkdir: %p/%s res=%p\n", parent, key->CName.Name,
+ result);
+#endif
+
/* init some fields for the directory record */
memset(&record, 0, sizeof(record));
record.cdrType = HFS_CDR_DIR;
@@ -1234,6 +1242,10 @@
struct hfs_mdb *mdb = parent->mdb;
int is_dir, error = 0;
+#if defined(DEBUG_CATALOG) || defined(DEBUG_ALL)
+ hfs_warn("hfs_cat_delete: %p/%p type=%d state=%lu, thread=%d\n",
+ parent, entry, entry->type, entry->state, with_thread);
+#endif
if (parent->mdb != entry->mdb) {
return -EINVAL;
}
@@ -1252,39 +1264,39 @@
if (entry->type == HFS_CDR_DIR) {
start_read(entry);
- if (entry->u.dir.files || entry->u.dir.dirs) {
- error = -ENOTEMPTY;
- }
+ error = -ENOTEMPTY;
+ if (entry->u.dir.files || entry->u.dir.dirs)
+ goto hfs_delete_end;
}
/* try to delete the file or directory */
- if (!error) {
- lock_entry(entry);
- if ((entry->state & HFS_DELETED)) {
- /* somebody beat us to it */
- error = -ENOENT;
- } else {
- error = hfs_bdelete(mdb->cat_tree,
- HFS_BKEY(&entry->key));
- }
- unlock_entry(entry);
+ lock_entry(entry);
+ error = -ENOENT;
+ if ((entry->state & HFS_DELETED)) {
+ /* somebody beat us to it. */
+ goto hfs_delete_unlock;
+ }
+
+ /* delete the catalog record */
+ if ((error = hfs_bdelete(mdb->cat_tree, HFS_BKEY(&entry->key)))) {
+ goto hfs_delete_unlock;
}
- if (!error) {
- /* Mark the entry deleted and remove it from the cache */
- lock_entry(entry);
- delete_entry(entry);
-
- /* try to delete the thread entry if it exists */
- if (with_thread) {
- hfs_cat_build_key(entry->cnid, NULL, &key);
- (void)hfs_bdelete(mdb->cat_tree, HFS_BKEY(&key));
- }
-
- unlock_entry(entry);
- update_dir(mdb, parent, is_dir, -1);
+ /* Mark the entry deleted and remove it from the cache */
+ delete_entry(entry);
+
+ /* try to delete the thread entry if it exists */
+ if (with_thread) {
+ hfs_cat_build_key(entry->cnid, NULL, &key);
+ (void)hfs_bdelete(mdb->cat_tree, HFS_BKEY(&key));
}
+
+ update_dir(mdb, parent, is_dir, -1);
+
+hfs_delete_unlock:
+ unlock_entry(entry);
+hfs_delete_end:
if (entry->type == HFS_CDR_DIR) {
end_read(entry);
}
@@ -1332,10 +1344,10 @@
return -EINVAL;
}
- spin_lock(&entry_lock);
while (mdb->rename_lock) {
hfs_sleep_on(&mdb->rename_wait);
}
+ spin_lock(&entry_lock);
mdb->rename_lock = 1;
spin_unlock(&entry_lock);
@@ -1575,5 +1587,3 @@
i--;
} while (i);
}
-
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov