static int ufs_rmdir (struct inode * dir, struct dentry *dentry) { struct inode * inode = d_inode(dentry); int err= -ENOTEMPTY; if (ufs_empty_dir (inode)) { err = ufs_unlink(dir, dentry); if (!err) { inode->i_size = 0; inode_dec_link_count(inode); inode_dec_link_count(dir); } } return err; }
int op_unlink (const char *path) { int rt; char *p_path; char *r_path; ino_t p_ino; struct ufs_vnode *p_vnode; ino_t r_ino; struct ufs_vnode *r_vnode; struct inode *r_inode; struct inode *p_inode; uufsd_t *ufs = current_ufs(); RETURN_IF_RDONLY(ufs); debugf("enter"); debugf("path = %s", path); rt = do_check_split(path, &p_path, &r_path); if (rt != 0) { debugf("do_check_split: failed"); return rt; } debugf("parent: %s, child: %s", p_path, r_path); rt = do_readvnode(ufs, p_path, &p_ino, &p_vnode); if (rt) { debugf("do_readinode(%s, &p_ino, &p_inode); failed", p_path); free_split(p_path, r_path); return rt; } rt = do_readvnode(ufs, path, &r_ino, &r_vnode); if (rt) { debugf("do_readvnode(%s, &r_ino, &r_vnode); failed", path); free_split(p_path, r_path); return rt; } r_inode = vnode2inode(r_vnode); if(S_ISDIR(r_inode->i_mode)) { debugf("%s is a directory", path); vnode_put(r_vnode, 0); free_split(p_path, r_path); return -EISDIR; } rt = ufs_unlink(ufs, p_ino, r_path, r_ino, 0); if (rt) { debugf("ufs_unlink(ufs, %d, %s, %d, 0); failed", p_ino, r_path, r_ino); vnode_put(r_vnode, 0); vnode_put(p_vnode, 0); free_split(p_path, r_path); return -EIO; } if (r_inode->i_nlink > 0) { r_inode->i_nlink -= 1; } p_inode = vnode2inode(p_vnode); p_inode->i_ctime = p_inode->i_mtime = ufs->now ? ufs->now : time(NULL); rt = vnode_put(p_vnode, 1); if (rt) { debugf("ufs_write_inode(ufs, p_ino, &p_inode); failed"); vnode_put(r_vnode,1); free_split(p_path, r_path); return -EIO; } r_inode->i_ctime = ufs->now ? ufs->now : time(NULL); rt = vnode_put(r_vnode, 1); if (rt) { debugf("vnode_put(r_vnode, 1); failed"); free_split(p_path, r_path); return -EIO; } free_split(p_path, r_path); debugf("leave"); return 0; }