12
12
/*
13
13
* For future. This should probably be per-directory.
14
14
*/
15
- static DEFINE_RWLOCK ( adfs_dir_lock );
15
+ static DECLARE_RWSEM ( adfs_dir_rwsem );
16
16
17
17
int adfs_dir_copyfrom (void * dst , struct adfs_dir * dir , unsigned int offset ,
18
18
size_t len )
@@ -232,39 +232,40 @@ adfs_readdir(struct file *file, struct dir_context *ctx)
232
232
if (ctx -> pos >> 32 )
233
233
return 0 ;
234
234
235
+ down_read (& adfs_dir_rwsem );
235
236
ret = adfs_dir_read_inode (sb , inode , & dir );
236
237
if (ret )
237
- return ret ;
238
+ goto unlock ;
238
239
239
240
if (ctx -> pos == 0 ) {
240
241
if (!dir_emit_dot (file , ctx ))
241
- goto free_out ;
242
+ goto unlock_relse ;
242
243
ctx -> pos = 1 ;
243
244
}
244
245
if (ctx -> pos == 1 ) {
245
246
if (!dir_emit (ctx , ".." , 2 , dir .parent_id , DT_DIR ))
246
- goto free_out ;
247
+ goto unlock_relse ;
247
248
ctx -> pos = 2 ;
248
249
}
249
250
250
- read_lock (& adfs_dir_lock );
251
-
252
251
ret = ops -> setpos (& dir , ctx -> pos - 2 );
253
252
if (ret )
254
- goto unlock_out ;
253
+ goto unlock_relse ;
255
254
while (ops -> getnext (& dir , & obj ) == 0 ) {
256
255
if (!dir_emit (ctx , obj .name , obj .name_len ,
257
256
obj .indaddr , DT_UNKNOWN ))
258
257
break ;
259
258
ctx -> pos ++ ;
260
259
}
261
260
262
- unlock_out :
263
- read_unlock (& adfs_dir_lock );
264
-
265
- free_out :
261
+ unlock_relse :
262
+ up_read (& adfs_dir_rwsem );
266
263
adfs_dir_relse (& dir );
267
264
return ret ;
265
+
266
+ unlock :
267
+ up_read (& adfs_dir_rwsem );
268
+ return ret ;
268
269
}
269
270
270
271
int
@@ -281,13 +282,13 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
281
282
if (!ops -> update )
282
283
return - EINVAL ;
283
284
285
+ down_write (& adfs_dir_rwsem );
284
286
ret = adfs_dir_read (sb , obj -> parent_id , 0 , & dir );
285
287
if (ret )
286
- goto out ;
288
+ goto unlock ;
287
289
288
- write_lock (& adfs_dir_lock );
289
290
ret = ops -> update (& dir , obj );
290
- write_unlock ( & adfs_dir_lock );
291
+ up_write ( & adfs_dir_rwsem );
291
292
292
293
if (ret == 0 )
293
294
adfs_dir_mark_dirty (& dir );
@@ -299,7 +300,10 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
299
300
}
300
301
301
302
adfs_dir_relse (& dir );
302
- out :
303
+ return ret ;
304
+
305
+ unlock :
306
+ up_write (& adfs_dir_rwsem );
303
307
#endif
304
308
return ret ;
305
309
}
@@ -336,17 +340,14 @@ static int adfs_dir_lookup_byname(struct inode *inode, const struct qstr *qstr,
336
340
u32 name_len ;
337
341
int ret ;
338
342
343
+ down_read (& adfs_dir_rwsem );
339
344
ret = adfs_dir_read_inode (sb , inode , & dir );
340
345
if (ret )
341
- goto out ;
342
-
343
- obj -> parent_id = inode -> i_ino ;
344
-
345
- read_lock (& adfs_dir_lock );
346
+ goto unlock ;
346
347
347
348
ret = ops -> setpos (& dir , 0 );
348
349
if (ret )
349
- goto unlock_out ;
350
+ goto unlock_relse ;
350
351
351
352
ret = - ENOENT ;
352
353
name = qstr -> name ;
@@ -357,13 +358,15 @@ static int adfs_dir_lookup_byname(struct inode *inode, const struct qstr *qstr,
357
358
break ;
358
359
}
359
360
}
361
+ obj -> parent_id = inode -> i_ino ;
360
362
361
- unlock_out :
362
- read_unlock (& adfs_dir_lock );
363
-
364
- free_out :
363
+ unlock_relse :
364
+ up_read (& adfs_dir_rwsem );
365
365
adfs_dir_relse (& dir );
366
- out :
366
+ return ret ;
367
+
368
+ unlock :
369
+ up_read (& adfs_dir_rwsem );
367
370
return ret ;
368
371
}
369
372
0 commit comments