aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:50:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:50:52 -0400
commit3f6f7e6d57b8a0ae2810ae7aac70c51b6f2a6304 (patch)
treeed4460a8f072cd088e225163bdeeafc5ce9fecb6 /fs
parent8f627a8a881481598c2591c3acc122fb9be7bac4 (diff)
parent31be83aeaee22fa165862ad449c7131ceaf1cf91 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bcopeland/omfs
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bcopeland/omfs: omfs: make readdir stop when filldir says so omfs: merge unlink() and rmdir(), close leak in rename() omfs: stop playing silly buggers with omfs_unlink() in ->rename() omfs: rename() needs to mark old_inode dirty after ctime update
Diffstat (limited to 'fs')
-rw-r--r--fs/omfs/dir.c66
1 files changed, 20 insertions, 46 deletions
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index 393f3f659da7..de4ff29f1e05 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -235,33 +235,22 @@ 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 if (S_ISDIR(inode->i_mode) && !omfs_dir_is_empty(inode))
244 return -ENOTEMPTY;
242 245
243 ret = omfs_delete_entry(dentry); 246 ret = omfs_delete_entry(dentry);
244 if (ret) 247 if (ret)
245 goto end_unlink; 248 return ret;
246 249
247 inode_dec_link_count(inode); 250 clear_nlink(inode);
251 mark_inode_dirty(inode);
248 mark_inode_dirty(dir); 252 mark_inode_dirty(dir);
249 253 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} 254}
266 255
267static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) 256static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode)
@@ -372,9 +361,10 @@ static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir,
372 361
373 res = filldir(dirent, oi->i_name, strnlen(oi->i_name, 362 res = filldir(dirent, oi->i_name, strnlen(oi->i_name,
374 OMFS_NAMELEN), filp->f_pos, self, d_type); 363 OMFS_NAMELEN), filp->f_pos, self, d_type);
375 if (res == 0)
376 filp->f_pos++;
377 brelse(bh); 364 brelse(bh);
365 if (res < 0)
366 break;
367 filp->f_pos++;
378 } 368 }
379out: 369out:
380 return res; 370 return res;
@@ -385,44 +375,28 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry,
385{ 375{
386 struct inode *new_inode = new_dentry->d_inode; 376 struct inode *new_inode = new_dentry->d_inode;
387 struct inode *old_inode = old_dentry->d_inode; 377 struct inode *old_inode = old_dentry->d_inode;
388 struct buffer_head *bh;
389 int is_dir;
390 int err; 378 int err;
391 379
392 is_dir = S_ISDIR(old_inode->i_mode);
393
394 if (new_inode) { 380 if (new_inode) {
395 /* overwriting existing file/dir */ 381 /* overwriting existing file/dir */
396 err = -ENOTEMPTY; 382 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) 383 if (err)
409 goto out; 384 goto out;
410 } 385 }
411 386
412 /* since omfs locates files by name, we need to unlink _before_ 387 /* since omfs locates files by name, we need to unlink _before_
413 * adding the new link or we won't find the old one */ 388 * adding the new link or we won't find the old one */
414 inode_inc_link_count(old_inode); 389 err = omfs_delete_entry(old_dentry);
415 err = omfs_unlink(old_dir, old_dentry); 390 if (err)
416 if (err) {
417 inode_dec_link_count(old_inode);
418 goto out; 391 goto out;
419 }
420 392
393 mark_inode_dirty(old_dir);
421 err = omfs_add_link(new_dentry, old_inode); 394 err = omfs_add_link(new_dentry, old_inode);
422 if (err) 395 if (err)
423 goto out; 396 goto out;
424 397
425 old_inode->i_ctime = CURRENT_TIME_SEC; 398 old_inode->i_ctime = CURRENT_TIME_SEC;
399 mark_inode_dirty(old_inode);
426out: 400out:
427 return err; 401 return err;
428} 402}
@@ -488,8 +462,8 @@ const struct inode_operations omfs_dir_inops = {
488 .mkdir = omfs_mkdir, 462 .mkdir = omfs_mkdir,
489 .rename = omfs_rename, 463 .rename = omfs_rename,
490 .create = omfs_create, 464 .create = omfs_create,
491 .unlink = omfs_unlink, 465 .unlink = omfs_remove,
492 .rmdir = omfs_rmdir, 466 .rmdir = omfs_remove,
493}; 467};
494 468
495const struct file_operations omfs_dir_operations = { 469const struct file_operations omfs_dir_operations = {