static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) { int err = ufs_add_link(dentry, inode); if (!err) { d_instantiate(dentry, inode); return 0; } inode_dec_link_count(inode); iput(inode); return err; }
static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode) { struct inode * inode; int err = -EMLINK; if (dir->i_nlink >= UFS_LINK_MAX) goto out; dquot_initialize(dir); lock_kernel(); inode_inc_link_count(dir); inode = ufs_new_inode(dir, S_IFDIR|mode); err = PTR_ERR(inode); if (IS_ERR(inode)) goto out_dir; inode->i_op = &ufs_dir_inode_operations; inode->i_fop = &ufs_dir_operations; inode->i_mapping->a_ops = &ufs_aops; inode_inc_link_count(inode); err = ufs_make_empty(inode, dir); if (err) goto out_fail; err = ufs_add_link(dentry, inode); if (err) goto out_fail; unlock_kernel(); d_instantiate(dentry, inode); out: return err; out_fail: inode_dec_link_count(inode); inode_dec_link_count(inode); iput (inode); out_dir: inode_dec_link_count(dir); unlock_kernel(); goto out; }
static int ufs_link (struct dentry * old_dentry, struct inode * dir, struct dentry *dentry) { struct inode *inode = d_inode(old_dentry); int error; inode->i_ctime = CURRENT_TIME_SEC; inode_inc_link_count(inode); ihold(inode); error = ufs_add_link(dentry, inode); if (error) { inode_dec_link_count(inode); iput(inode); } else d_instantiate(dentry, inode); return error; }
static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) { struct inode * inode; int err; lock_ufs(dir->i_sb); inode_inc_link_count(dir); inode = ufs_new_inode(dir, S_IFDIR|mode); err = PTR_ERR(inode); if (IS_ERR(inode)) goto out_dir; inode->i_op = &ufs_dir_inode_operations; inode->i_fop = &ufs_dir_operations; inode->i_mapping->a_ops = &ufs_aops; inode_inc_link_count(inode); err = ufs_make_empty(inode, dir); if (err) goto out_fail; err = ufs_add_link(dentry, inode); if (err) goto out_fail; unlock_ufs(dir->i_sb); unlock_new_inode(inode); d_instantiate(dentry, inode); out: return err; out_fail: inode_dec_link_count(inode); inode_dec_link_count(inode); unlock_new_inode(inode); iput (inode); out_dir: inode_dec_link_count(dir); unlock_ufs(dir->i_sb); goto out; }
static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct page *dir_page = NULL; struct ufs_dir_entry * dir_de = NULL; struct page *old_page; struct ufs_dir_entry *old_de; int err = -ENOENT; old_de = ufs_find_entry(old_dir, old_dentry, &old_page); if (!old_de) goto out; if (S_ISDIR(old_inode->i_mode)) { err = -EIO; dir_de = ufs_dotdot(old_inode, &dir_page); if (!dir_de) goto out_old; } if (new_inode) { struct page *new_page; struct ufs_dir_entry *new_de; err = -ENOTEMPTY; if (dir_de && !ufs_empty_dir(new_inode)) goto out_dir; err = -ENOENT; new_de = ufs_find_entry(new_dir, new_dentry, &new_page); if (!new_de) goto out_dir; inode_inc_link_count(old_inode); ufs_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { err = -EMLINK; if (new_dir->i_nlink >= UFS_LINK_MAX) goto out_dir; } inode_inc_link_count(old_inode); err = ufs_add_link(new_dentry, old_inode); if (err) { inode_dec_link_count(old_inode); goto out_dir; } if (dir_de) inode_inc_link_count(new_dir); } /* * Like most other Unix systems, set the ctime for inodes on a * rename. * inode_dec_link_count() will mark the inode dirty. */ old_inode->i_ctime = CURRENT_TIME_SEC; ufs_delete_entry(old_dir, old_de, old_page); inode_dec_link_count(old_inode); if (dir_de) { ufs_set_link(old_inode, dir_de, dir_page, new_dir); inode_dec_link_count(old_dir); } return 0; out_dir: if (dir_de) { kunmap(dir_page); page_cache_release(dir_page); } out_old: kunmap(old_page); page_cache_release(old_page); out: return err; }
static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct page *dir_page = NULL; struct ufs_dir_entry * dir_de = NULL; struct page *old_page; struct ufs_dir_entry *old_de; int err = -ENOENT; old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_de) goto out; if (S_ISDIR(old_inode->i_mode)) { err = -EIO; dir_de = ufs_dotdot(old_inode, &dir_page); if (!dir_de) goto out_old; } if (new_inode) { struct page *new_page; struct ufs_dir_entry *new_de; err = -ENOTEMPTY; if (dir_de && !ufs_empty_dir(new_inode)) goto out_dir; err = -ENOENT; new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); if (!new_de) goto out_dir; ufs_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { err = ufs_add_link(new_dentry, old_inode); if (err) goto out_dir; if (dir_de) inode_inc_link_count(new_dir); } /* */ old_inode->i_ctime = CURRENT_TIME_SEC; ufs_delete_entry(old_dir, old_de, old_page); mark_inode_dirty(old_inode); if (dir_de) { ufs_set_link(old_inode, dir_de, dir_page, new_dir); inode_dec_link_count(old_dir); } return 0; out_dir: if (dir_de) { kunmap(dir_page); page_cache_release(dir_page); } out_old: kunmap(old_page); page_cache_release(old_page); out: return err; }
static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { struct inode *old_inode = d_inode(old_dentry); struct inode *new_inode = d_inode(new_dentry); struct page *dir_page = NULL; struct ufs_dir_entry * dir_de = NULL; struct page *old_page; struct ufs_dir_entry *old_de; int err = -ENOENT; if (flags & ~RENAME_NOREPLACE) return -EINVAL; old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_de) goto out; if (S_ISDIR(old_inode->i_mode)) { err = -EIO; dir_de = ufs_dotdot(old_inode, &dir_page); if (!dir_de) goto out_old; } if (new_inode) { struct page *new_page; struct ufs_dir_entry *new_de; err = -ENOTEMPTY; if (dir_de && !ufs_empty_dir(new_inode)) goto out_dir; err = -ENOENT; new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); if (!new_de) goto out_dir; ufs_set_link(new_dir, new_de, new_page, old_inode, 1); new_inode->i_ctime = current_time(new_inode); if (dir_de) drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { err = ufs_add_link(new_dentry, old_inode); if (err) goto out_dir; if (dir_de) inode_inc_link_count(new_dir); } /* * Like most other Unix systems, set the ctime for inodes on a * rename. */ old_inode->i_ctime = current_time(old_inode); ufs_delete_entry(old_dir, old_de, old_page); mark_inode_dirty(old_inode); if (dir_de) { if (old_dir != new_dir) ufs_set_link(old_inode, dir_de, dir_page, new_dir, 0); else { kunmap(dir_page); put_page(dir_page); } inode_dec_link_count(old_dir); } return 0; out_dir: if (dir_de) { kunmap(dir_page); put_page(dir_page); } out_old: kunmap(old_page); put_page(old_page); out: return err; }