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)
{
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;
}
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)