summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/adfs/dir.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index e8aafc65d545..ff9c921be31c 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -12,7 +12,7 @@
/*
* For future. This should probably be per-directory.
*/
-static DEFINE_RWLOCK(adfs_dir_lock);
+static DECLARE_RWSEM(adfs_dir_rwsem);
int adfs_dir_copyfrom(void *dst, struct adfs_dir *dir, unsigned int offset,
size_t len)
@@ -232,26 +232,25 @@ adfs_readdir(struct file *file, struct dir_context *ctx)
if (ctx->pos >> 32)
return 0;
+ down_read(&adfs_dir_rwsem);
ret = adfs_dir_read_inode(sb, inode, &dir);
if (ret)
- return ret;
+ goto unlock;
if (ctx->pos == 0) {
if (!dir_emit_dot(file, ctx))
- goto free_out;
+ goto unlock_relse;
ctx->pos = 1;
}
if (ctx->pos == 1) {
if (!dir_emit(ctx, "..", 2, dir.parent_id, DT_DIR))
- goto free_out;
+ goto unlock_relse;
ctx->pos = 2;
}
- read_lock(&adfs_dir_lock);
-
ret = ops->setpos(&dir, ctx->pos - 2);
if (ret)
- goto unlock_out;
+ goto unlock_relse;
while (ops->getnext(&dir, &obj) == 0) {
if (!dir_emit(ctx, obj.name, obj.name_len,
obj.indaddr, DT_UNKNOWN))
@@ -259,12 +258,14 @@ adfs_readdir(struct file *file, struct dir_context *ctx)
ctx->pos++;
}
-unlock_out:
- read_unlock(&adfs_dir_lock);
-
-free_out:
+unlock_relse:
+ up_read(&adfs_dir_rwsem);
adfs_dir_relse(&dir);
return ret;
+
+unlock:
+ up_read(&adfs_dir_rwsem);
+ return ret;
}
int
@@ -281,13 +282,13 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
if (!ops->update)
return -EINVAL;
+ down_write(&adfs_dir_rwsem);
ret = adfs_dir_read(sb, obj->parent_id, 0, &dir);
if (ret)
- goto out;
+ goto unlock;
- write_lock(&adfs_dir_lock);
ret = ops->update(&dir, obj);
- write_unlock(&adfs_dir_lock);
+ up_write(&adfs_dir_rwsem);
if (ret == 0)
adfs_dir_mark_dirty(&dir);
@@ -299,7 +300,10 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
}
adfs_dir_relse(&dir);
-out:
+ return ret;
+
+unlock:
+ up_write(&adfs_dir_rwsem);
#endif
return ret;
}
@@ -336,17 +340,14 @@ static int adfs_dir_lookup_byname(struct inode *inode, const struct qstr *qstr,
u32 name_len;
int ret;
+ down_read(&adfs_dir_rwsem);
ret = adfs_dir_read_inode(sb, inode, &dir);
if (ret)
- goto out;
-
- obj->parent_id = inode->i_ino;
-
- read_lock(&adfs_dir_lock);
+ goto unlock;
ret = ops->setpos(&dir, 0);
if (ret)
- goto unlock_out;
+ goto unlock_relse;
ret = -ENOENT;
name = qstr->name;
@@ -357,13 +358,15 @@ static int adfs_dir_lookup_byname(struct inode *inode, const struct qstr *qstr,
break;
}
}
+ obj->parent_id = inode->i_ino;
-unlock_out:
- read_unlock(&adfs_dir_lock);
-
-free_out:
+unlock_relse:
+ up_read(&adfs_dir_rwsem);
adfs_dir_relse(&dir);
-out:
+ return ret;
+
+unlock:
+ up_read(&adfs_dir_rwsem);
return ret;
}