struct dentry *simplefs_lookup(struct inode *parent_inode, struct dentry *child_dentry, unsigned int flags) { struct simplefs_inode *parent = SIMPLEFS_INODE(parent_inode); struct super_block *sb = parent_inode->i_sb; struct buffer_head *bh; struct simplefs_dir_record *record; int i; bh = sb_bread(sb, parent->data_block_number); BUG_ON(!bh); sfs_trace("Lookup in: ino=%llu, b=%llu\n", parent->inode_no, parent->data_block_number); record = (struct simplefs_dir_record *)bh->b_data; for (i = 0; i < parent->dir_children_count; i++) { sfs_trace("Have file: '%s' (ino=%llu)\n", record->filename, record->inode_no); if (!strcmp(record->filename, child_dentry->d_name.name)) { /* FIXME: There is a corner case where if an allocated inode, * is not written to the inode store, but the inodes_count is * incremented. Then if the random string on the disk matches * with the filename that we are comparing above, then we * will use an invalid uninitialized inode */ struct inode *inode = simplefs_iget(sb, record->inode_no); inode_init_owner(inode, parent_inode, SIMPLEFS_INODE(inode)->mode); d_add(child_dentry, inode); return NULL; } record++; } printk(KERN_ERR "No inode found for the filename [%s]\n", child_dentry->d_name.name); return NULL; }
/* We keep the dirent list sorted in increasing order of name hash, and we use the same hash function as the dentries. Makes this nice and simple */ static struct dentry *jffs3_lookup(struct inode *dir_i, struct dentry *target, struct nameidata *nd) { struct jffs3_inode_info *dir_f; struct jffs3_sb_info *c; struct jffs3_full_dirent *fd = NULL, *fd_list; uint32_t ino = 0; struct inode *inode = NULL; DBG_VFS(1, "entering\n"); dir_f = JFFS3_INODE_INFO(dir_i); c = JFFS3_SB_INFO(dir_i->i_sb); down(&dir_f->sem); /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */ for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) { if (fd_list->nhash == target->d_name.hash && (!fd || fd_list->version > fd->version) && strlen(fd_list->name) == target->d_name.len && !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) { fd = fd_list; } } if (fd) ino = fd->ino; up(&dir_f->sem); if (ino) { inode = iget(dir_i->i_sb, ino); if (!inode) { WARNING_MSG("iget() failed for ino #%u\n", ino); return (ERR_PTR(-EIO)); } } d_add(target, inode); return NULL; }
static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct dentry *ret = NULL; struct sysfs_dirent *parent_sd = dentry->d_parent->d_fsdata; struct sysfs_dirent *sd; struct inode *inode; mutex_lock(&sysfs_mutex); sd = sysfs_find_dirent(parent_sd, dentry->d_name.name); /* no such entry */ if (!sd) { ret = ERR_PTR(-ENOENT); goto out_unlock; } /* attach dentry and inode */ inode = sysfs_get_inode(dir->i_sb, sd); if (!inode) { ret = ERR_PTR(-ENOMEM); goto out_unlock; } /* instantiate and hash dentry */ ret = d_find_alias(inode); if (!ret) { dentry->d_op = &sysfs_dentry_ops; dentry->d_fsdata = sysfs_get(sd); d_add(dentry, inode); } else { d_move(ret, dentry); iput(inode); } out_unlock: mutex_unlock(&sysfs_mutex); return ret; }
static struct dentry *capifs_root_lookup(struct inode * dir, struct dentry * dentry) { struct capifs_sb_info *sbi = SBI(dir->i_sb); struct capifs_ncci *np; unsigned int i; char numbuf[32]; char *p, *tmp; unsigned int num; char type = 0; dentry->d_inode = NULL; /* Assume failure */ dentry->d_op = &capifs_dentry_operations; if (dentry->d_name.len >= sizeof(numbuf) ) return NULL; strncpy(numbuf, dentry->d_name.name, dentry->d_name.len); numbuf[dentry->d_name.len] = 0; p = numbuf; if (!isdigit(*p)) type = *p++; tmp = p; num = (unsigned int)simple_strtoul(p, &tmp, 10); if (tmp == p || *tmp) return NULL; for (i = 0, np = sbi->nccis ; i < sbi->max_ncci; i++, np++) { if (np->used && np->num == num && np->type == type) break; } if ( i >= sbi->max_ncci ) return NULL; dentry->d_inode = np->inode; if ( dentry->d_inode ) atomic_inc(&dentry->d_inode->i_count); d_add(dentry, dentry->d_inode); return NULL; }
struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root, char const * name) { struct dentry * dentry; struct inode * inode; struct qstr qname; qname.name = name; qname.len = strlen(name); qname.hash = full_name_hash(qname.name, qname.len); dentry = d_alloc(root, &qname); if (!dentry) return 0; inode = oprofilefs_get_inode(sb, S_IFDIR | 0755); if (!inode) { dput(dentry); return 0; } inode->i_op = &oprofilefs_dir_inode_operations; inode->i_fop = &oprofilefs_dir_operations; d_add(dentry, inode); return dentry; }
static int sel_make_initcon_files(struct dentry *dir) { int i; for (i = 1; i <= SECINITSID_NUM; i++) { struct inode *inode; struct dentry *dentry; dentry = d_alloc_name(dir, security_get_initial_sid_context(i)); if (!dentry) return -ENOMEM; inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); if (!inode) return -ENOMEM; inode->i_fop = &sel_initcon_ops; inode->i_ino = i|SEL_INITCON_INO_OFFSET; d_add(dentry, inode); } return 0; }
static struct dentry *usbdevfs_bus_lookup(struct inode *dir, struct dentry *dentry) { struct inode *inode; int devnr; /* sanity check */ if (ITYPE(dir->i_ino) != IBUS) return ERR_PTR(-EINVAL); dentry->d_op = &usbdevfs_dentry_operations; devnr = dnumber(dentry); if (devnr < 1 || devnr > 127) return ERR_PTR(-ENOENT); inode = iget(dir->i_sb, IDEVICE | (dir->i_ino & (0xff << 8)) | devnr); if (!inode) return ERR_PTR(-EINVAL); if (inode && inode->u.usbdev_i.p.dev == NULL) { iput(inode); inode = NULL; } d_add(dentry, inode); return NULL; }
/** * devpts_pty_new -- create a new inode in /dev/pts/ * @ptmx_inode: inode of the master * @device: major+minor of the node to be created * @index: used as a name of the node * @priv: what's given back by devpts_get_priv * * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill. */ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, void *priv) { struct dentry *dentry; struct super_block *sb = pts_sb_from_inode(ptmx_inode); struct inode *inode; struct dentry *root = sb->s_root; struct pts_fs_info *fsi = DEVPTS_SB(sb); struct pts_mount_opts *opts = &fsi->mount_opts; char s[12]; inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); inode->i_ino = index + 3; inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; init_special_inode(inode, S_IFCHR|opts->mode, device); inode->i_private = priv; sprintf(s, "%d", index); mutex_lock(&root->d_inode->i_mutex); dentry = d_alloc_name(root, s); if (dentry) { d_add(dentry, inode); fsnotify_create(root->d_inode, dentry); } else { iput(inode); inode = ERR_PTR(-ENOMEM); } mutex_unlock(&root->d_inode->i_mutex); return inode; }
static int ext4_lookup(struct inode *parent, struct dentry *dentry, struct nameidata *nd) { unsigned long ino; struct inode *inode; ino = ext4_inode_by_name(parent, &dentry->d_name); if (!ino) { // ... return -ENOENT; } inode = ext4_iget(parent->i_sb, ino); if (!inode) { // ... return -EIO; } // dentry->d_inode = inode; d_add(dentry, inode); return 0; }
/* We keep the dirent list sorted in increasing order of name hash, and we use the same hash function as the dentries. Makes this nice and simple */ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target) { struct jffs2_inode_info *dir_f; struct jffs2_sb_info *c; struct jffs2_full_dirent *fd = NULL, *fd_list; __u32 ino = 0; struct inode *inode = NULL; D1(printk(KERN_DEBUG "jffs2_lookup()\n")); dir_f = JFFS2_INODE_INFO(dir_i); c = JFFS2_SB_INFO(dir_i->i_sb); down(&dir_f->sem); /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */ for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) { if (fd_list->nhash == target->d_name.hash && (!fd || fd_list->version > fd->version) && strlen(fd_list->name) == target->d_name.len && !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) { fd = fd_list; } } if (fd) ino = fd->ino; up(&dir_f->sem); if (ino) { inode = iget(dir_i->i_sb, ino); if (!inode) { printk(KERN_WARNING "iget() failed for ino #%u\n", ino); return (ERR_PTR(-EIO)); } } d_add(target, inode); return NULL; }
/** * vxfs_lookup - lookup pathname component * @dip: dir in which we lookup * @dp: dentry we lookup * @nd: lookup nameidata * * Description: * vxfs_lookup tries to lookup the pathname component described * by @dp in @dip. * * Returns: * A NULL-pointer on success, else an negative error code encoded * in the return pointer. */ static struct dentry * vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) { struct inode *ip = NULL; ino_t ino; if (dp->d_name.len > VXFS_NAMELEN) return ERR_PTR(-ENAMETOOLONG); lock_kernel(); ino = vxfs_inode_by_name(dip, dp); if (ino) { ip = vxfs_iget(dip->i_sb, ino); if (IS_ERR(ip)) { unlock_kernel(); return ERR_CAST(ip); } } unlock_kernel(); d_add(dp, ip); return NULL; }
STATIC struct dentry * xfs_vn_lookup( struct inode *dir, struct dentry *dentry, struct nameidata *nd) { bhv_vnode_t *cvp; int error; if (dentry->d_name.len >= MAXNAMELEN) return ERR_PTR(-ENAMETOOLONG); error = xfs_lookup(XFS_I(dir), dentry, &cvp); if (unlikely(error)) { if (unlikely(error != ENOENT)) return ERR_PTR(-error); d_add(dentry, NULL); return NULL; } return d_splice_alias(vn_to_inode(cvp), dentry); }
STATIC struct dentry * linvfs_lookup( struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct vnode *vp = LINVFS_GET_VP(dir), *cvp; int error; if (dentry->d_name.len >= MAXNAMELEN) return ERR_PTR(-ENAMETOOLONG); VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error); if (error) { if (unlikely(error != ENOENT)) return ERR_PTR(-error); d_add(dentry, NULL); return NULL; } return d_splice_alias(LINVFS_GET_IP(cvp), dentry); }
/* Connect a wrapfs inode dentry/inode with several lower ones. This is * the classic stackable file system "vnode interposition" action. * * @dentry: wrapfs's dentry which interposes on lower one * @sb: wrapfs's super_block * @lower_path: the lower path (caller does path_get/put) */ int wrapfs_interpose(struct dentry *dentry, struct super_block *sb, struct path *lower_path) { int err = 0; struct inode *inode; struct inode *lower_inode; struct super_block *lower_sb; lower_inode = lower_path->dentry->d_inode; lower_sb = wrapfs_lower_super(sb); /* check that the lower file system didn't cross a mount point */ if (lower_inode->i_sb != lower_sb) { err = -EXDEV; goto out; } /* * We allocate our new inode below by calling wrapfs_iget, * which will initialize some of the new inode's fields */ /* inherit lower inode number for wrapfs's inode */ inode = wrapfs_new_iget(sb, iunique(sb, 1)); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out; } if (atomic_read(&inode->i_count) > 1) goto out_add; wrapfs_fill_inode(dentry, inode); printk(KERN_INFO" U2fs_interpose success\n"); out_add: d_add(dentry, inode); out: return err; }
static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd) { struct btstack btstack; ino_t inum; struct inode *ip; struct component_name key; const char *name = dentry->d_name.name; int len = dentry->d_name.len; int rc; jfs_info("jfs_lookup: name = %s", name); if ((name[0] == '.') && (len == 1)) inum = dip->i_ino; else if (strcmp(name, "..") == 0) inum = PARENT(dip); else { if ((rc = get_UCSname(&key, dentry))) return ERR_PTR(rc); rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP); free_UCSname(&key); if (rc == -ENOENT) { d_add(dentry, NULL); return NULL; } else if (rc) { jfs_err("jfs_lookup: dtSearch returned %d", rc); return ERR_PTR(rc); } } ip = jfs_iget(dip->i_sb, inum); if (IS_ERR(ip)) { jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum); return ERR_CAST(ip); } return d_splice_alias(ip, dentry); }
int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) { int number = tty->index; /* tty layer puts index from devpts_new_index() in here */ struct tty_driver *driver = tty->driver; dev_t device = MKDEV(driver->major, driver->minor_start+number); struct dentry *dentry; struct inode *inode = new_inode(devpts_mnt->mnt_sb); char s[12]; /* We're supposed to be given the slave end of a pty */ BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); BUG_ON(driver->subtype != PTY_TYPE_SLAVE); if (!inode) return -ENOMEM; inode->i_ino = number+2; inode->i_uid = config.setuid ? config.uid : current_fsuid(); inode->i_gid = config.setgid ? config.gid : current_fsgid(); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; init_special_inode(inode, S_IFCHR|config.mode, device); inode->i_private = tty; tty->driver_data = inode; sprintf(s, "%d", number); mutex_lock(&devpts_root->d_inode->i_mutex); dentry = d_alloc_name(devpts_root, s); if (!IS_ERR(dentry)) { d_add(dentry, inode); fsnotify_create(devpts_root->d_inode, dentry); } mutex_unlock(&devpts_root->d_inode->i_mutex); return 0; }
struct dentry * ux_lookup(struct inode *dip, struct dentry *dentry) { struct ux_inode *uip = (struct ux_inode *) &dip->i_private; struct ux_dirent dirent; struct inode *inode = NULL; int inum; if (dentry->d_name.len > UX_NAMELEN) { return ERR_PTR(-ENAMETOOLONG); } inum = ux_find_entry(dip, (char *)dentry->d_name.name); if (inum) { inode = ux_iget(dip->i_sb, inum); if (IS_ERR(inode)) { return ERR_CAST(inode); } } d_add(dentry, inode); return NULL; }
static int proc_ns_instantiate(struct inode *dir, struct dentry *dentry, struct task_struct *task, const void *ptr) { const struct proc_ns_operations *ns_ops = ptr; struct inode *inode; struct proc_inode *ei; inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK | S_IRWXUGO); if (!inode) goto out; ei = PROC_I(inode); inode->i_op = &proc_ns_link_inode_operations; ei->ns_ops = ns_ops; d_set_d_op(dentry, &pid_dentry_operations); d_add(dentry, inode); /* Close the race of the process dying before we return the dentry */ if (pid_revalidate(dentry, 0)) return 0; out: return -ENOENT; }
static struct _dentry * __oprofilefs_create_file(struct super_block * sb, struct _dentry * root, char const * name, const struct file_operations * fops, int perm) { struct dentry * dentry; struct _dentry * _dentry; struct inode * inode; struct _inode * _inode; dentry = d_alloc_name(root, name); if (!dentry) return NULL; inode = oprofilefs_get_inode(sb, S_IFREG | perm); if (!inode) { dput(dentry); return NULL; } _inode = tx_cache_get_inode(inode); _inode->i_fop = fops; _dentry = tx_cache_get_dentry(dentry); d_add(_dentry, _inode); return _dentry; }
struct dentry * affs_lookup(struct inode *dir, struct dentry *dentry) { unsigned long ino; struct buffer_head *bh; struct inode *inode; pr_debug("AFFS: lookup(\"%.*s\")\n",(int)dentry->d_name.len,dentry->d_name.name); inode = NULL; bh = affs_find_entry(dir,dentry,&ino); if (bh) { if (FILE_END(bh->b_data,dir)->original) ino = be32_to_cpu(FILE_END(bh->b_data,dir)->original); affs_brelse(bh); inode = iget(dir->i_sb,ino); if (!inode) return ERR_PTR(-EACCES); } dentry->d_op = &affs_dentry_operations; d_add(dentry,inode); return NULL; }
struct dentry *oprofilefs_mkdir(struct dentry *parent, char const *name) { struct dentry *dentry; struct inode *inode; inode_lock(d_inode(parent)); dentry = d_alloc_name(parent, name); if (!dentry) { inode_unlock(d_inode(parent)); return NULL; } inode = oprofilefs_get_inode(parent->d_sb, S_IFDIR | 0755); if (!inode) { dput(dentry); inode_unlock(d_inode(parent)); return NULL; } inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; d_add(dentry, inode); inode_unlock(d_inode(parent)); return dentry; }
static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d) { struct inode *res = 0; char *item = 0; ntfs_iterate_s walk; int err; ntfs_debug(DEBUG_NAME1, __FUNCTION__ "(): Looking up %s in directory " "ino 0x%x.\n", d->d_name.name, (unsigned)dir->i_ino); walk.name = NULL; walk.namelen = 0; /* Convert to wide string. */ err = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name, d->d_name.len, &walk.name, &walk.namelen); if (err) goto err_ret; item = ntfs_malloc(ITEM_SIZE); if (!item) { err = -ENOMEM; goto err_ret; } /* ntfs_getdir will place the directory entry into item, and the first * long long is the MFT record number. */ walk.type = BY_NAME; walk.dir = NTFS_LINO2NINO(dir); walk.result = item; if (ntfs_getdir_byname(&walk)) res = iget(dir->i_sb, NTFS_GETU32(item)); d_add(d, res); ntfs_free(item); ntfs_free(walk.name); /* Always return success, the dcache will handle negative entries. */ return NULL; err_ret: ntfs_free(walk.name); return ERR_PTR(err); }
static int proc_sys_fill_cache(struct file *filp, void *dirent, filldir_t filldir, struct ctl_table_header *head, struct ctl_table *table) { struct dentry *child, *dir = filp->f_path.dentry; struct inode *inode; struct qstr qname; ino_t ino = 0; unsigned type = DT_UNKNOWN; qname.name = table->procname; qname.len = strlen(table->procname); qname.hash = full_name_hash(qname.name, qname.len); child = d_lookup(dir, &qname); if (!child) { child = d_alloc(dir, &qname); if (child) { inode = proc_sys_make_inode(dir->d_sb, head, table); if (!inode) { dput(child); return -ENOMEM; } else { d_set_d_op(child, &proc_sys_dentry_operations); d_add(child, inode); } } else { return -ENOMEM; } } inode = child->d_inode; ino = inode->i_ino; type = inode->i_mode >> 12; dput(child); return !!filldir(dirent, qname.name, qname.len, filp->f_pos, ino, type); }
STATIC struct dentry * xfs_vn_lookup( struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct xfs_inode *cip; struct xfs_name name; int error; if (dentry->d_name.len >= MAXNAMELEN) return ERR_PTR(-ENAMETOOLONG); xfs_dentry_to_name(&name, dentry); error = xfs_lookup(XFS_I(dir), &name, &cip, NULL); if (unlikely(error)) { if (unlikely(error != ENOENT)) return ERR_PTR(-error); d_add(dentry, NULL); return NULL; } return d_splice_alias(VFS_I(cip), dentry); }
struct _dentry * oprofilefs_mkdir(struct super_block * sb, struct _dentry * root, char const * name) { struct dentry * dentry; struct _dentry * _dentry; struct inode * inode; struct _inode * _inode; dentry = d_alloc_name(root, name); if (!dentry) return NULL; inode = oprofilefs_get_inode(sb, S_IFDIR | 0755); if (!inode) { dput(dentry); return NULL; } _inode = tx_cache_get_inode(inode); _inode->i_op = &simple_dir_inode_operations; _inode->i_fop = &simple_dir_operations; _dentry = tx_cache_get_dentry(dentry); d_add(_dentry, _inode); return _dentry; }
static int __oprofilefs_create_file(struct dentry *root, char const *name, const struct file_operations *fops, int perm, void *priv) { struct dentry *dentry; struct inode *inode; inode_lock(d_inode(root)); dentry = d_alloc_name(root, name); if (!dentry) { inode_unlock(d_inode(root)); return -ENOMEM; } inode = oprofilefs_get_inode(root->d_sb, S_IFREG | perm); if (!inode) { dput(dentry); inode_unlock(d_inode(root)); return -ENOMEM; } inode->i_fop = fops; inode->i_private = priv; d_add(dentry, inode); inode_unlock(d_inode(root)); return 0; }
/* * Connect a amfs inode dentry/inode with several lower ones. This is * the classic stackable file system "vnode interposition" action. * * @dentry: amfs's dentry which interposes on lower one * @sb: amfs's super_block * @lower_path: the lower path (caller does path_get/put) */ int amfs_interpose(struct dentry *dentry, struct super_block *sb, struct path *lower_path) { int err = 0; struct inode *inode; struct inode *lower_inode; struct super_block *lower_sb; lower_inode = lower_path->dentry->d_inode; lower_sb = amfs_lower_super(sb); // printk("\n lookup.c->amfs_interpose"); //aditi /* check that the lower file system didn't cross a mount point */ if (lower_inode->i_sb != lower_sb) { err = -EXDEV; goto out; } /* * We allocate our new inode below by calling amfs_iget, * which will initialize some of the new inode's fields */ /* inherit lower inode number for amfs's inode */ inode = amfs_iget(sb, lower_inode); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out; } d_add(dentry, inode); out: return err; }
/** * devpts_pty_new -- create a new inode in /dev/pts/ * @ptmx_inode: inode of the master * @device: major+minor of the node to be created * @index: used as a name of the node * @priv: what's given back by devpts_get_priv * * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill. */ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) { struct dentry *dentry; struct super_block *sb = fsi->sb; struct inode *inode; struct dentry *root; struct pts_mount_opts *opts; char s[12]; root = sb->s_root; opts = &fsi->mount_opts; inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); inode->i_ino = index + 3; inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); init_special_inode(inode, S_IFCHR|opts->mode, MKDEV(UNIX98_PTY_SLAVE_MAJOR, index)); sprintf(s, "%d", index); dentry = d_alloc_name(root, s); if (dentry) { dentry->d_fsdata = priv; d_add(dentry, inode); fsnotify_create(d_inode(root), dentry); } else { iput(inode); dentry = ERR_PTR(-ENOMEM); } return dentry; }
struct dentry * affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct super_block *sb = dir->i_sb; struct buffer_head *bh; struct inode *inode = NULL; pr_debug("AFFS: lookup(\"%.*s\")\n",(int)dentry->d_name.len,dentry->d_name.name); affs_lock_dir(dir); bh = affs_find_entry(dir, dentry); affs_unlock_dir(dir); if (IS_ERR(bh)) { return ERR_PTR(PTR_ERR(bh)); } if (bh) { u32 ino = bh->b_blocknr; /* store the real header ino in d_fsdata for faster lookups */ dentry->d_fsdata = (void *)(long)ino; switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) { //link to dirs disabled //case ST_LINKDIR: case ST_LINKFILE: ino = be32_to_cpu(AFFS_TAIL(sb, bh)->original); } affs_brelse(bh); inode = iget(sb, ino); if (!inode) { return ERR_PTR(-EACCES); } } dentry->d_op = AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations; d_add(dentry, inode); return NULL; }
int sysv_lookup(struct inode * dir, struct dentry * dentry) { struct inode * inode = NULL; struct sysv_dir_entry * de; struct buffer_head * bh; if (!dir) return -ENOENT; if (!S_ISDIR(dir->i_mode)) { return -ENOENT; } bh = sysv_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); if (bh) { int ino = de->inode; brelse(bh); inode = iget(dir->i_sb, ino); if (!inode) return -EACCES; } d_add(dentry, inode); return 0; }