diff options
Diffstat (limited to 'fs/omfs/dir.c')
-rw-r--r-- | fs/omfs/dir.c | 68 |
1 files changed, 22 insertions, 46 deletions
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index 393f3f659da7..3b8d3979e03b 100644 --- a/fs/omfs/dir.c +++ b/fs/omfs/dir.c | |||
@@ -235,33 +235,24 @@ static int omfs_dir_is_empty(struct inode *inode) | |||
235 | return *ptr != ~0; | 235 | return *ptr != ~0; |
236 | } | 236 | } |
237 | 237 | ||
238 | static int omfs_unlink(struct inode *dir, struct dentry *dentry) | 238 | static int omfs_remove(struct inode *dir, struct dentry *dentry) |
239 | { | 239 | { |
240 | int ret; | ||
241 | struct inode *inode = dentry->d_inode; | 240 | struct inode *inode = dentry->d_inode; |
241 | int ret; | ||
242 | |||
243 | |||
244 | if (S_ISDIR(inode->i_mode) && | ||
245 | !omfs_dir_is_empty(inode)) | ||
246 | return -ENOTEMPTY; | ||
242 | 247 | ||
243 | ret = omfs_delete_entry(dentry); | 248 | ret = omfs_delete_entry(dentry); |
244 | if (ret) | 249 | if (ret) |
245 | goto end_unlink; | 250 | return ret; |
246 | 251 | ||
247 | inode_dec_link_count(inode); | 252 | clear_nlink(inode); |
253 | mark_inode_dirty(inode); | ||
248 | mark_inode_dirty(dir); | 254 | mark_inode_dirty(dir); |
249 | 255 | return 0; | |
250 | end_unlink: | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | static int omfs_rmdir(struct inode *dir, struct dentry *dentry) | ||
255 | { | ||
256 | int err = -ENOTEMPTY; | ||
257 | struct inode *inode = dentry->d_inode; | ||
258 | |||
259 | if (omfs_dir_is_empty(inode)) { | ||
260 | err = omfs_unlink(dir, dentry); | ||
261 | if (!err) | ||
262 | inode_dec_link_count(inode); | ||
263 | } | ||
264 | return err; | ||
265 | } | 256 | } |
266 | 257 | ||
267 | static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) | 258 | static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) |
@@ -372,9 +363,10 @@ static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir, | |||
372 | 363 | ||
373 | res = filldir(dirent, oi->i_name, strnlen(oi->i_name, | 364 | res = filldir(dirent, oi->i_name, strnlen(oi->i_name, |
374 | OMFS_NAMELEN), filp->f_pos, self, d_type); | 365 | OMFS_NAMELEN), filp->f_pos, self, d_type); |
375 | if (res == 0) | ||
376 | filp->f_pos++; | ||
377 | brelse(bh); | 366 | brelse(bh); |
367 | if (res < 0) | ||
368 | break; | ||
369 | filp->f_pos++; | ||
378 | } | 370 | } |
379 | out: | 371 | out: |
380 | return res; | 372 | return res; |
@@ -385,44 +377,28 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
385 | { | 377 | { |
386 | struct inode *new_inode = new_dentry->d_inode; | 378 | struct inode *new_inode = new_dentry->d_inode; |
387 | struct inode *old_inode = old_dentry->d_inode; | 379 | struct inode *old_inode = old_dentry->d_inode; |
388 | struct buffer_head *bh; | ||
389 | int is_dir; | ||
390 | int err; | 380 | int err; |
391 | 381 | ||
392 | is_dir = S_ISDIR(old_inode->i_mode); | ||
393 | |||
394 | if (new_inode) { | 382 | if (new_inode) { |
395 | /* overwriting existing file/dir */ | 383 | /* overwriting existing file/dir */ |
396 | err = -ENOTEMPTY; | 384 | err = omfs_remove(new_dir, new_dentry); |
397 | if (is_dir && !omfs_dir_is_empty(new_inode)) | ||
398 | goto out; | ||
399 | |||
400 | err = -ENOENT; | ||
401 | bh = omfs_find_entry(new_dir, new_dentry->d_name.name, | ||
402 | new_dentry->d_name.len); | ||
403 | if (IS_ERR(bh)) | ||
404 | goto out; | ||
405 | brelse(bh); | ||
406 | |||
407 | err = omfs_unlink(new_dir, new_dentry); | ||
408 | if (err) | 385 | if (err) |
409 | goto out; | 386 | goto out; |
410 | } | 387 | } |
411 | 388 | ||
412 | /* since omfs locates files by name, we need to unlink _before_ | 389 | /* since omfs locates files by name, we need to unlink _before_ |
413 | * adding the new link or we won't find the old one */ | 390 | * adding the new link or we won't find the old one */ |
414 | inode_inc_link_count(old_inode); | 391 | err = omfs_delete_entry(old_dentry); |
415 | err = omfs_unlink(old_dir, old_dentry); | 392 | if (err) |
416 | if (err) { | ||
417 | inode_dec_link_count(old_inode); | ||
418 | goto out; | 393 | goto out; |
419 | } | ||
420 | 394 | ||
395 | mark_inode_dirty(old_dir); | ||
421 | err = omfs_add_link(new_dentry, old_inode); | 396 | err = omfs_add_link(new_dentry, old_inode); |
422 | if (err) | 397 | if (err) |
423 | goto out; | 398 | goto out; |
424 | 399 | ||
425 | old_inode->i_ctime = CURRENT_TIME_SEC; | 400 | old_inode->i_ctime = CURRENT_TIME_SEC; |
401 | mark_inode_dirty(old_inode); | ||
426 | out: | 402 | out: |
427 | return err; | 403 | return err; |
428 | } | 404 | } |
@@ -488,8 +464,8 @@ const struct inode_operations omfs_dir_inops = { | |||
488 | .mkdir = omfs_mkdir, | 464 | .mkdir = omfs_mkdir, |
489 | .rename = omfs_rename, | 465 | .rename = omfs_rename, |
490 | .create = omfs_create, | 466 | .create = omfs_create, |
491 | .unlink = omfs_unlink, | 467 | .unlink = omfs_remove, |
492 | .rmdir = omfs_rmdir, | 468 | .rmdir = omfs_remove, |
493 | }; | 469 | }; |
494 | 470 | ||
495 | const struct file_operations omfs_dir_operations = { | 471 | const struct file_operations omfs_dir_operations = { |