aboutsummaryrefslogtreecommitdiffstats
path: root/fs/omfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/omfs/dir.c')
-rw-r--r--fs/omfs/dir.c68
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
238static int omfs_unlink(struct inode *dir, struct dentry *dentry) 238static 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;
250end_unlink:
251 return ret;
252}
253
254static 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
267static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) 258static 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 }
379out: 371out:
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);
426out: 402out:
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
495const struct file_operations omfs_dir_operations = { 471const struct file_operations omfs_dir_operations = {