Exemple #1
0
struct inode *search_inode_for_lustre(struct super_block *sb,
				      const struct lu_fid *fid)
{
	struct ll_sb_info     *sbi = ll_s2sbi(sb);
	struct ptlrpc_request *req = NULL;
	struct inode	  *inode = NULL;
	int		   eadatalen = 0;
	unsigned long	      hash = cl_fid_build_ino(fid,
						      ll_need_32bit_api(sbi));
	struct  md_op_data    *op_data;
	int		   rc;

	CDEBUG(D_INFO, "searching inode for:(%lu,"DFID")\n", hash, PFID(fid));

	inode = ilookup5(sb, hash, ll_nfs_test_inode, (void *)fid);
	if (inode)
		return inode;

	rc = ll_get_default_mdsize(sbi, &eadatalen);
	if (rc)
		return ERR_PTR(rc);

	/* Because inode is NULL, ll_prep_md_op_data can not
	 * be used here. So we allocate op_data ourselves */
	op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
	if (!op_data)
		return ERR_PTR(-ENOMEM);

	op_data->op_fid1 = *fid;
	op_data->op_mode = eadatalen;
	op_data->op_valid = OBD_MD_FLEASIZE;

	/* mds_fid2dentry ignores f_type */
	rc = md_getattr(sbi->ll_md_exp, op_data, &req);
	kfree(op_data);
	if (rc) {
		CERROR("can't get object attrs, fid "DFID", rc %d\n",
		       PFID(fid), rc);
		return ERR_PTR(rc);
	}
	rc = ll_prep_inode(&inode, req, sb, NULL);
	ptlrpc_req_finished(req);
	if (rc)
		return ERR_PTR(rc);

	return inode;
}
Exemple #2
0
int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data,
		struct dir_context *ctx)
{
	struct ll_sb_info    *sbi	= ll_i2sbi(inode);
	__u64		   pos		= *ppos;
	int		   is_api32 = ll_need_32bit_api(sbi);
	int		   is_hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH;
	struct page	  *page;
	bool		   done = false;
	int		   rc = 0;

	page = ll_get_dir_page(inode, op_data, pos);

	while (rc == 0 && !done) {
		struct lu_dirpage *dp;
		struct lu_dirent  *ent;
		__u64 hash;
		__u64 next;

		if (IS_ERR(page)) {
			rc = PTR_ERR(page);
			break;
		}

		hash = MDS_DIR_END_OFF;
		dp = page_address(page);
		for (ent = lu_dirent_start(dp); ent && !done;
		     ent = lu_dirent_next(ent)) {
			__u16	  type;
			int	    namelen;
			struct lu_fid  fid;
			__u64	  lhash;
			__u64	  ino;

			hash = le64_to_cpu(ent->lde_hash);
			if (hash < pos)
				/*
				 * Skip until we find target hash
				 * value.
				 */
				continue;

			namelen = le16_to_cpu(ent->lde_namelen);
			if (namelen == 0)
				/*
				 * Skip dummy record.
				 */
				continue;

			if (is_api32 && is_hash64)
				lhash = hash >> 32;
			else
				lhash = hash;
			fid_le_to_cpu(&fid, &ent->lde_fid);
			ino = cl_fid_build_ino(&fid, is_api32);
			type = ll_dirent_type_get(ent);
			ctx->pos = lhash;
			/* For 'll_nfs_get_name_filldir()', it will try
			 * to access the 'ent' through its 'lde_name',
			 * so the parameter 'name' for 'ctx->actor()'
			 * must be part of the 'ent'.
			 */
			done = !dir_emit(ctx, ent->lde_name,
					 namelen, ino, type);
		}

		if (done) {
			pos = hash;
			ll_release_page(inode, page, false);
			break;
		}

		next = le64_to_cpu(dp->ldp_hash_end);
		pos = next;
		if (pos == MDS_DIR_END_OFF) {
			/*
			 * End of directory reached.
			 */
			done = 1;
			ll_release_page(inode, page, false);
		} else {
			/*
			 * Normal case: continue to the next
			 * page.
			 */
			ll_release_page(inode, page,
					le32_to_cpu(dp->ldp_flags) &
					LDF_COLLIDE);
			next = pos;
			page = ll_get_dir_page(inode, op_data, pos);
		}
	}