]> git.neil.brown.name Git - LaFS.git/commitdiff
flush orphans when renaming to empty directory just like rmdir
authorNeilBrown <neilb@suse.de>
Sat, 14 Aug 2010 11:50:14 +0000 (21:50 +1000)
committerNeilBrown <neilb@suse.de>
Sat, 14 Aug 2010 11:50:14 +0000 (21:50 +1000)
Signed-off-by: NeilBrown <neilb@suse.de>
dir.c

diff --git a/dir.c b/dir.c
index 0985428040acb41af4aec51b1606dbc1ea678a67..b2df67aafb458cad3c5506baeb246e713abecfb3 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -787,6 +787,29 @@ abort:
        return err;
 }
 
+static void dir_flush_orphans(struct fs *fs, struct inode *inode)
+{
+       /*
+        * Orphans cannot clear while we hold i_mutex, so
+        * we have to run them ourselves.
+        */
+       struct datablock *db;
+       DEFINE_WAIT(wq);
+       while ((db = lafs_find_orphan(inode))) {
+               int still_orphan;
+               prepare_to_wait(&fs->async_complete, &wq,
+                               TASK_UNINTERRUPTIBLE);
+               getdref(db, MKREF(rmdir_orphan));
+               lafs_dir_handle_orphan(db);
+               still_orphan = test_bit(B_Orphan, &db->b.flags);
+               putdref(db, MKREF(rmdir_orphan));
+               if (still_orphan)
+                       /* still an orphan, need to wait */
+                       schedule();
+       }
+       finish_wait(&fs->async_complete, &wq);
+}
+
 static int
 lafs_rmdir(struct inode *dir, struct dentry *de)
 {
@@ -802,24 +825,8 @@ lafs_rmdir(struct inode *dir, struct dentry *de)
        if (inode->i_size) {
                /* Probably not empty, but it could be that we
                 * just need to wait for orphans the clear.
-                * They cannot clear while we hold i_mutex, so
-                * we have to run it ourselves.
                 */
-               struct datablock *db;
-               DEFINE_WAIT(wq);
-               while ((db = lafs_find_orphan(inode))) {
-                       int still_orphan;
-                       prepare_to_wait(&fs->async_complete, &wq,
-                                       TASK_UNINTERRUPTIBLE);
-                       getdref(db, MKREF(rmdir_orphan));
-                       lafs_dir_handle_orphan(db);
-                       still_orphan = test_bit(B_Orphan, &db->b.flags);
-                       putdref(db, MKREF(rmdir_orphan));
-                       if (still_orphan)
-                               /* still an orphan, need to wait */
-                               schedule();
-               }
-               finish_wait(&fs->async_complete, &wq);
+               dir_flush_orphans(fs, inode);
                if (inode->i_size)
                        return -ENOTEMPTY;
        }
@@ -1123,9 +1130,11 @@ lafs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        if (S_ISDIR(old_inode->i_mode)) {
                if (new_inode) {
-                       /* FIXME flush orphans in new_inode */
-                       if (new_inode->i_size)
-                               return -ENOTEMPTY;
+                       if (new_inode->i_size) {
+                               dir_flush_orphans(fs, new_inode);
+                               if (new_inode->i_size)
+                                       return -ENOTEMPTY;
+                       }
                } else if (new_dir != old_dir) {
                        /* New dir is getting a new link */
                        if (new_dir->i_nlink >= LAFS_MAX_LINKS)