/* Get a reference to the blockdevice at @pathname in the current namespace if possible and return it. Return ERR_PTR(error) otherwise.  */
struct block_device* lookup_bdev(const char *pathname)
/* Get a reference to the blockdevice at @pathname in the current namespace if possible and return it. Return ERR_PTR(error) otherwise.  */
struct block_device* lookup_bdev(const char *pathname)
{
	struct block_device *bdev;
	struct inode *inode;
	struct path path;
	int error;
	if (!pathname || !*pathname)
		return ERR_PTR(-EINVAL);
	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
	if (error)
		return ERR_PTR(error);
	inode = path.dentry->d_inode;
	error = -ENOTBLK;
	if (!S_ISBLK(inode->i_mode))
		goto fail;
	error = -EACCES;
	if (path.mnt->mnt_flags & MNT_NODEV)
		goto fail;
	error = -ENOMEM;
	bdev = bd_acquire(inode);
	if (!bdev)
		goto fail;
out:
	path_put(&path);
	return bdev;
fail:
	bdev = ERR_PTR(error);
	goto out;
}