]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] make hfs use regular semaphores
authorAlexander Viro <viro@math.psu.edu>
Sun, 21 Jul 2002 03:47:10 +0000 (20:47 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 21 Jul 2002 03:47:10 +0000 (20:47 -0700)
unrelated to the rest, replaces home-grown (racy) semaphores in fs/hfs
with the real thing.

fs/hfs/binsert.c
fs/hfs/btree.c
fs/hfs/catalog.c
fs/hfs/hfs.h
fs/hfs/hfs_btree.h

index 6f0853892dcb5505be3978d57d08d120f88aa138..7fe11c3b88d337ad2832ff1364dfdf3f6bb7b56b 100644 (file)
 #include "hfs_btree.h"
 
 /*================ File-local functions ================*/
-
-/* btree locking functions */
-static inline void hfs_btree_lock(struct hfs_btree *tree)
-{
-  while (tree->lock) 
-    hfs_sleep_on(&tree->wait);
-  tree->lock = 1;
-}
-
-static inline void hfs_btree_unlock(struct hfs_btree *tree)
-{
-  tree->lock = 0;
-  hfs_wake_up(&tree->wait);
-}
-
 /*
  * binsert_nonfull()
  *
@@ -526,11 +511,11 @@ restart:
                /* make certain we have enough nodes to proceed */
                if ((tree->bthFree - tree->reserved) < reserve) {
                        hfs_brec_relse(&brec, NULL);
-                       hfs_btree_lock(tree);
+                       down(&tree->sem);
                        if ((tree->bthFree - tree->reserved) < reserve) {
                                hfs_btree_extend(tree);
                        }
-                       hfs_btree_unlock(tree);
+                       up(&tree->sem);
                        if ((tree->bthFree - tree->reserved) < reserve) {
                                return -ENOSPC;
                        } else {
index bc23f94c26de520eaa383eca2f9ae1b04e00acad..f14bb508e134eab427bc26f5e7a0f1ff895b3b40 100644 (file)
@@ -172,8 +172,7 @@ struct hfs_btree * hfs_btree_init(struct hfs_mdb *mdb, ino_t cnid,
        bt->magic = HFS_BTREE_MAGIC;
        bt->sys_mdb = mdb->sys_mdb;
        bt->reserved = 0;
-       bt->lock = 0;
-       hfs_init_waitqueue(&bt->wait);
+       sema_init(&bt->sem, 1);
        bt->dirt = 0;
        memset(bt->cache, 0, sizeof(bt->cache));
 
index a82753c462d91f51641aa169f39c1a45a1d58afb..b036b1f2186e9f114aeca25af874094a07ab4e1b 100644 (file)
@@ -302,8 +302,7 @@ static void __read_entry(struct hfs_cat_entry *entry,
                entry->modify_date = hfs_get_nl(cat->u.dir.MdDat);
                entry->backup_date = hfs_get_nl(cat->u.dir.BkDat);
                dir->dirs = dir->files = 0;
-               hfs_init_waitqueue(&dir->read_wait);
-               hfs_init_waitqueue(&dir->write_wait);
+               init_rwsem(&dir->sem);
        } else if (cat->cdrType == HFS_CDR_FIL) {
                struct hfs_file *fil = &entry->u.file;
 
@@ -641,51 +640,6 @@ static void update_dir(struct hfs_mdb *mdb, struct hfs_cat_entry *dir,
        hfs_cat_mark_dirty(dir);
 }
 
-/*
- * Add a writer to dir, excluding readers.
- *
- * XXX: this is wrong. it allows a move to occur when a directory
- *      is being written to. 
- */
-static inline void start_write(struct hfs_cat_entry *dir)
-{
-       if (dir->u.dir.readers || waitqueue_active(&dir->u.dir.read_wait)) {
-               hfs_sleep_on(&dir->u.dir.write_wait);
-       }
-       ++dir->u.dir.writers;
-}
-
-/*
- * Add a reader to dir, excluding writers.
- */
-static inline void start_read(struct hfs_cat_entry *dir)
-{
-       if (dir->u.dir.writers || waitqueue_active(&dir->u.dir.write_wait)) {
-               hfs_sleep_on(&dir->u.dir.read_wait);
-       }
-       ++dir->u.dir.readers;
-}
-
-/*
- * Remove a writer from dir, possibly admitting readers.
- */
-static inline void end_write(struct hfs_cat_entry *dir)
-{
-       if (!(--dir->u.dir.writers)) {
-               hfs_wake_up(&dir->u.dir.read_wait);
-       }
-}
-
-/*
- * Remove a reader from dir, possibly admitting writers.
- */
-static inline void end_read(struct hfs_cat_entry *dir)
-{
-       if (!(--dir->u.dir.readers)) {
-               hfs_wake_up(&dir->u.dir.write_wait);
-       }
-}
-
 /*
  * create_entry()
  *
@@ -707,7 +661,7 @@ static int create_entry(struct hfs_cat_entry *parent, struct hfs_cat_key *key,
        }
 
        /* keep readers from getting confused by changing dir size */
-       start_write(parent);
+       down_write(&parent->u.dir.sem);
 
        /* create a locked entry in the cache */
        entry = get_entry(mdb, key, 0);
@@ -782,7 +736,7 @@ bail1:
 bail2:
        hfs_cat_put(entry);
 done:
-       end_write(parent);
+       up_write(&parent->u.dir.sem);
        return error;
 }
 
@@ -1058,21 +1012,19 @@ int hfs_cat_open(struct hfs_cat_entry *dir, struct hfs_brec *brec)
        struct hfs_cat_key key;
        int error;
 
-       if (dir->type != HFS_CDR_DIR) {
+       if (dir->type != HFS_CDR_DIR)
                return -EINVAL;
-       }
        
        /* Block writers */
-       start_read(dir);
+       down_read(&dir->u.dir.sem);
 
        /* Find the directory */
        hfs_cat_build_key(dir->cnid, NULL, &key);
        error = hfs_bfind(brec, dir->mdb->cat_tree,
                          HFS_BKEY(&key), HFS_BFIND_READ_EQ);
 
-       if (error) {
-               end_read(dir);
-       }
+       if (error)
+               up_read(&dir->u.dir.sem);
 
        return error;
 }
@@ -1109,7 +1061,7 @@ int hfs_cat_next(struct hfs_cat_entry *dir, struct hfs_brec *brec,
                *type = ((struct hfs_cat_rec *)brec->data)->cdrType;
                *cnid = brec_to_id(brec);
        } else {
-               end_read(dir);
+               up_read(&dir->u.dir.sem);
        }
        return error;
 }
@@ -1127,7 +1079,7 @@ void hfs_cat_close(struct hfs_cat_entry *dir, struct hfs_brec *brec)
 {
        if (dir && brec) {
                hfs_brec_relse(brec, NULL);
-               end_read(dir);
+               up_read(&dir->u.dir.sem);
        }
 }
 
@@ -1260,11 +1212,11 @@ int hfs_cat_delete(struct hfs_cat_entry *parent, struct hfs_cat_entry *entry,
        }
 
        /* keep readers from getting confused by changing dir size */
-       start_write(parent);
+       down_write(&parent->u.dir.sem);
 
        /* don't delete a busy directory */
        if (entry->type == HFS_CDR_DIR) {
-               start_read(entry);
+               down_read(&entry->u.dir.sem);
 
                error = -ENOTEMPTY;
                if (entry->u.dir.files || entry->u.dir.dirs) 
@@ -1299,10 +1251,9 @@ hfs_delete_unlock:
        unlock_entry(entry);
 
 hfs_delete_end:
-       if (entry->type == HFS_CDR_DIR) {
-               end_read(entry);
-       }
-       end_write(parent);
+       if (entry->type == HFS_CDR_DIR)
+               up_read(&entry->u.dir.sem);
+       up_write(&parent->u.dir.sem);
        return error;
 }
 
@@ -1347,10 +1298,10 @@ int hfs_cat_move(struct hfs_cat_entry *old_dir, struct hfs_cat_entry *new_dir,
        }
 
        /* keep readers from getting confused by changing dir size */
-       start_write(new_dir);
-       if (old_dir != new_dir) {
-               start_write(old_dir);
-       }
+       down_write(&new_dir->u.dir.sem);
+       /* AV: smells like a deadlock */
+       if (old_dir != new_dir)
+               down_write(&old_dir->u.dir.sem);
 
        /* Don't move a directory inside itself */
        if (is_dir) {
@@ -1556,10 +1507,9 @@ bail3:
                hfs_cat_put(dest);
        }
 done:
-       if (new_dir != old_dir) {
-               end_write(old_dir);
-       }
-       end_write(new_dir);
+       if (new_dir != old_dir)
+               up_write(&old_dir->u.dir.sem);
+       up_write(&new_dir->u.dir.sem);
        return error;
 }
 
index ad9f70d742943884aaf5adfc6e5e64ab7be6e0e9..adf912cbec0ccc90c952d7ba5c223e6a1fe28862 100644 (file)
@@ -310,10 +310,7 @@ struct hfs_dir {
        hfs_u16         flags;
        hfs_u16         dirs;           /* Number of directories in this one */
        hfs_u16         files;          /* Number of files in this directory */
-       int             readers;
-       hfs_wait_queue  read_wait;
-       int             writers;
-       hfs_wait_queue  write_wait;
+       struct rw_semaphore     sem;
 };
 
 /*
index c3371bfa883dd1b493f8a16b70caa1c5b83ecff7..b4bc1069ecfdba4482f7383c45c4354740364a8e 100644 (file)
@@ -194,8 +194,7 @@ struct hfs_btree {
        struct hfs_bnode                       /* The bnode cache */
                                *cache[HFS_CACHELEN];
        struct hfs_cat_entry    entry;         /* Fake catalog entry */
-       int                     lock;
-       hfs_wait_queue          wait;
+       struct semaphore        sem;
        int                     dirt;
        int                     keySize;   
        /* Fields from the BTHdrRec in native byte-order: */