struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { int ino; struct qnx4_inode_entry *de; struct qnx4_link_info *lnk; struct buffer_head *bh; const char *name = dentry->d_name.name; int len = dentry->d_name.len; struct inode *foundinode = NULL; lock_kernel(); if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino))) goto out; /* The entry is linked, let's get the real info */ if ((de->di_status & QNX4_FILE_LINK) == QNX4_FILE_LINK) { lnk = (struct qnx4_link_info *) de; ino = (le32_to_cpu(lnk->dl_inode_blk) - 1) * QNX4_INODES_PER_BLOCK + lnk->dl_inode_ndx; } brelse(bh); foundinode = qnx4_iget(dir->i_sb, ino); if (IS_ERR(foundinode)) { unlock_kernel(); QNX4DEBUG(("qnx4: lookup->iget -> error %ld\n", PTR_ERR(foundinode))); return ERR_CAST(foundinode); } out: unlock_kernel(); d_add(dentry, foundinode); return NULL; }
struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { int ino; struct qnx4_inode_entry *de; struct qnx4_link_info *lnk; struct buffer_head *bh; const char *name = dentry->d_name.name; int len = dentry->d_name.len; struct inode *foundinode = NULL; if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino))) goto out; /* The entry is linked, let's get the real info */ if ((de->di_status & QNX4_FILE_LINK) == QNX4_FILE_LINK) { lnk = (struct qnx4_link_info *) de; ino = (le32_to_cpu(lnk->dl_inode_blk) - 1) * QNX4_INODES_PER_BLOCK + lnk->dl_inode_ndx; } brelse(bh); foundinode = qnx4_iget(dir->i_sb, ino); if (IS_ERR(foundinode)) QNX4DEBUG((KERN_ERR "qnx4: lookup->iget -> error %ld\n", PTR_ERR(foundinode))); out: return d_splice_alias(foundinode, dentry); }
int qnx4_rmdir(struct inode *dir, struct dentry *dentry) { struct buffer_head *bh; struct qnx4_inode_entry *de; struct inode *inode; int retval; int ino; QNX4DEBUG(("qnx4: qnx4_rmdir [%s]\n", dentry->d_name.name)); lock_kernel(); bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name, &de, &ino); if (bh == NULL) { unlock_kernel(); return -ENOENT; } inode = dentry->d_inode; if (inode->i_ino != ino) { retval = -EIO; goto end_rmdir; } #if 0 if (!empty_dir(inode)) { retval = -ENOTEMPTY; goto end_rmdir; } #endif if (inode->i_nlink != 2) { QNX4DEBUG(("empty directory has nlink!=2 (%d)\n", inode->i_nlink)); } QNX4DEBUG(("qnx4: deleting directory\n")); de->di_status = 0; memset(de->di_fname, 0, sizeof de->di_fname); de->di_mode = 0; mark_buffer_dirty(bh); inode->i_nlink = 0; mark_inode_dirty(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; dir->i_nlink--; mark_inode_dirty(dir); retval = 0; end_rmdir: brelse(bh); unlock_kernel(); return retval; }
int qnx4_unlink(struct inode *dir, struct dentry *dentry) { struct buffer_head *bh; struct qnx4_inode_entry *de; struct inode *inode; int retval; int ino; QNX4DEBUG(("qnx4: qnx4_unlink [%s]\n", dentry->d_name.name)); lock_kernel(); bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name, &de, &ino); if (bh == NULL) { unlock_kernel(); return -ENOENT; } inode = dentry->d_inode; if (inode->i_ino != ino) { retval = -EIO; goto end_unlink; } retval = -EPERM; if (!inode->i_nlink) { QNX4DEBUG(("Deleting nonexistent file (%s:%lu), %d\n", inode->i_sb->s_id, inode->i_ino, inode->i_nlink)); inode->i_nlink = 1; } de->di_status = 0; memset(de->di_fname, 0, sizeof de->di_fname); de->di_mode = 0; mark_buffer_dirty(bh); dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); inode->i_nlink--; inode->i_ctime = dir->i_ctime; mark_inode_dirty(inode); retval = 0; end_unlink: unlock_kernel(); brelse(bh); return retval; }