예제 #1
0
파일: mmap.c 프로젝트: 3sOx/asuswrt-merlin
static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
{
	sigset_t blocked, oldset;
	int error, ret;

	mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff);

	/* The best way to deal with signals in this path is
	 * to block them upfront, rather than allowing the
	 * locking paths to return -ERESTARTSYS. */
	sigfillset(&blocked);

	/* We should technically never get a bad ret return
	 * from sigprocmask */
	error = sigprocmask(SIG_BLOCK, &blocked, &oldset);
	if (ret < 0) {
		mlog_errno(error);
		ret = VM_FAULT_SIGBUS;
		goto out;
	}

	ret = filemap_fault(area, vmf);

	error = sigprocmask(SIG_SETMASK, &oldset, NULL);
	if (error < 0)
		mlog_errno(error);
out:
	mlog_exit_ptr(vmf->page);
	return ret;
}
예제 #2
0
파일: export.c 프로젝트: 274914765/C
static struct dentry *ocfs2_get_dentry(struct super_block *sb,
        struct ocfs2_inode_handle *handle)
{
    struct inode *inode;
    struct dentry *result;

    mlog_entry("(0x%p, 0x%p)\n", sb, handle);

    if (handle->ih_blkno == 0) {
        mlog_errno(-ESTALE);
        return ERR_PTR(-ESTALE);
    }

    inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno, 0, 0);

    if (IS_ERR(inode))
        return (void *)inode;

    if (handle->ih_generation != inode->i_generation) {
        iput(inode);
        return ERR_PTR(-ESTALE);
    }

    result = d_alloc_anon(inode);

    if (!result) {
        iput(inode);
        mlog_errno(-ENOMEM);
        return ERR_PTR(-ENOMEM);
    }
    result->d_op = &ocfs2_dentry_ops;

    mlog_exit_ptr(result);
    return result;
}
예제 #3
0
static struct page *ocfs2_nopage(struct vm_area_struct * area,
				 unsigned long address,
				 int *type)
{
	struct page *page = NOPAGE_SIGBUS;
	sigset_t blocked, oldset;
	int ret;

	mlog_entry("(area=%p, address=%lu, type=%p)\n", area, address,
		   type);

	/* The best way to deal with signals in this path is
	 * to block them upfront, rather than allowing the
	 * locking paths to return -ERESTARTSYS. */
	sigfillset(&blocked);

	/* We should technically never get a bad ret return
	 * from sigprocmask */
	ret = sigprocmask(SIG_BLOCK, &blocked, &oldset);
	if (ret < 0) {
		mlog_errno(ret);
		goto out;
	}

	page = filemap_nopage(area, address, type);

	ret = sigprocmask(SIG_SETMASK, &oldset, NULL);
	if (ret < 0)
		mlog_errno(ret);
out:
	mlog_exit_ptr(page);
	return page;
}
예제 #4
0
static struct dentry *ocfs2_get_parent(struct dentry *child)
{
	int status;
	u64 blkno;
	struct dentry *parent;
	struct inode *inode;
	struct inode *dir = child->d_inode;
	struct buffer_head *dirent_bh = NULL;
	struct ocfs2_dir_entry *dirent;

	mlog_entry("(0x%p, '%.*s')\n", child,
		   child->d_name.len, child->d_name.name);

	mlog(0, "find parent of directory %llu\n",
	     (unsigned long long)OCFS2_I(dir)->ip_blkno);

	status = ocfs2_meta_lock(dir, NULL, 0);
	if (status < 0) {
		if (status != -ENOENT)
			mlog_errno(status);
		parent = ERR_PTR(status);
		goto bail;
	}

	status = ocfs2_find_files_on_disk("..", 2, &blkno, dir, &dirent_bh,
					  &dirent);
	if (status < 0) {
		parent = ERR_PTR(-ENOENT);
		goto bail_unlock;
	}

	inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0);
	if (IS_ERR(inode)) {
		mlog(ML_ERROR, "Unable to create inode %llu\n",
		     (unsigned long long)blkno);
		parent = ERR_PTR(-EACCES);
		goto bail_unlock;
	}

	parent = d_alloc_anon(inode);
	if (!parent) {
		iput(inode);
		parent = ERR_PTR(-ENOMEM);
	}

	parent->d_op = &ocfs2_dentry_ops;

bail_unlock:
	ocfs2_meta_unlock(dir, 0);

	if (dirent_bh)
		brelse(dirent_bh);

bail:
	mlog_exit_ptr(parent);

	return parent;
}
예제 #5
0
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,
			 int sysfile_type)
{
	struct inode *inode = NULL;
	struct super_block *sb = osb->sb;
	struct ocfs2_find_inode_args args;

	mlog_entry("(blkno = %llu)\n", (unsigned long long)blkno);

	/* Ok. By now we've either got the offsets passed to us by the
	 * caller, or we just pulled them off the bh. Lets do some
	 * sanity checks to make sure they're OK. */
	if (blkno == 0) {
		inode = ERR_PTR(-EINVAL);
		mlog_errno(PTR_ERR(inode));
		goto bail;
	}

	args.fi_blkno = blkno;
	args.fi_flags = flags;
	args.fi_ino = ino_from_blkno(sb, blkno);
	args.fi_sysfile_type = sysfile_type;

	inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor,
			     ocfs2_init_locked_inode, &args);
	/* inode was *not* in the inode cache. 2.6.x requires
	 * us to do our own read_inode call and unlock it
	 * afterwards. */
	if (inode && inode->i_state & I_NEW) {
		mlog(0, "Inode was not in inode cache, reading it.\n");
		ocfs2_read_locked_inode(inode, &args);
		unlock_new_inode(inode);
	}
	if (inode == NULL) {
		inode = ERR_PTR(-ENOMEM);
		mlog_errno(PTR_ERR(inode));
		goto bail;
	}
	if (is_bad_inode(inode)) {
		iput(inode);
		inode = ERR_PTR(-ESTALE);
		goto bail;
	}

bail:
	if (!IS_ERR(inode)) {
		mlog(0, "returning inode with number %llu\n",
		     (unsigned long long)OCFS2_I(inode)->ip_blkno);
		mlog_exit_ptr(inode);
	}

	return inode;
}
예제 #6
0
파일: mmap.c 프로젝트: asdlei00/Ace-i
static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
{
    sigset_t oldset;
    int ret;

    mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff);

    ocfs2_block_signals(&oldset);
    ret = filemap_fault(area, vmf);
    ocfs2_unblock_signals(&oldset);

    mlog_exit_ptr(vmf->page);
    return ret;
}
예제 #7
0
static struct dentry *ocfs2_decode_fh(struct super_block *sb, u32 *fh_in,
				      int fh_len, int fileid_type,
				      int (*acceptable)(void *context,
						        struct dentry *de),
				      void *context)
{
	struct ocfs2_inode_handle handle, parent;
	struct dentry *ret = NULL;
	__le32 *fh = (__force __le32 *) fh_in;

	mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n",
		   sb, fh, fh_len, fileid_type, acceptable, context);

	if (fh_len < 3 || fileid_type > 2)
		goto bail;

	if (fileid_type == 2) {
		if (fh_len < 6)
			goto bail;

		parent.ih_blkno = (u64)le32_to_cpu(fh[3]) << 32;
		parent.ih_blkno |= (u64)le32_to_cpu(fh[4]);
		parent.ih_generation = le32_to_cpu(fh[5]);

		mlog(0, "Decoding parent: blkno: %llu, generation: %u\n",
		     (unsigned long long)parent.ih_blkno,
		     parent.ih_generation);
	}

	handle.ih_blkno = (u64)le32_to_cpu(fh[0]) << 32;
	handle.ih_blkno |= (u64)le32_to_cpu(fh[1]);
	handle.ih_generation = le32_to_cpu(fh[2]);

	mlog(0, "Encoding fh: blkno: %llu, generation: %u\n",
	     (unsigned long long)handle.ih_blkno, handle.ih_generation);

	ret = ocfs2_export_ops.find_exported_dentry(sb, &handle, &parent,
						    acceptable, context);

bail:
	mlog_exit_ptr(ret);
	return ret;
}
예제 #8
0
static struct dentry *ocfs2_get_parent(struct dentry *child)
{
	int status;
	u64 blkno;
	struct dentry *parent;
	struct inode *dir = child->d_inode;

	mlog_entry("(0x%p, '%.*s')\n", child,
		   child->d_name.len, child->d_name.name);

	mlog(0, "find parent of directory %llu\n",
	     (unsigned long long)OCFS2_I(dir)->ip_blkno);

	status = ocfs2_inode_lock(dir, NULL, 0);
	if (status < 0) {
		if (status != -ENOENT)
			mlog_errno(status);
		parent = ERR_PTR(status);
		goto bail;
	}

	status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
	if (status < 0) {
		parent = ERR_PTR(-ENOENT);
		goto bail_unlock;
	}

	parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
	if (!IS_ERR(parent))
		parent->d_op = &ocfs2_dentry_ops;

bail_unlock:
	ocfs2_inode_unlock(dir, 0);

bail:
	mlog_exit_ptr(parent);

	return parent;
}
예제 #9
0
static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
{
	sigset_t blocked, oldset;
	int error, ret;

	mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff);

	error = ocfs2_vm_op_block_sigs(&blocked, &oldset);
	if (error < 0) {
		mlog_errno(error);
		ret = VM_FAULT_SIGBUS;
		goto out;
	}

	ret = filemap_fault(area, vmf);

	error = ocfs2_vm_op_unblock_sigs(&oldset);
	if (error < 0)
		mlog_errno(error);
out:
	mlog_exit_ptr(vmf->page);
	return ret;
}
예제 #10
0
static struct dentry *ocfs2_get_dentry(struct super_block *sb,
		struct ocfs2_inode_handle *handle)
{
	struct inode *inode;
	struct ocfs2_super *osb = OCFS2_SB(sb);
	u64 blkno = handle->ih_blkno;
	int status, set;
	struct dentry *result;

	mlog_entry("(0x%p, 0x%p)\n", sb, handle);

	if (blkno == 0) {
		mlog(0, "nfs wants inode with blkno: 0\n");
		result = ERR_PTR(-ESTALE);
		goto bail;
	}

	inode = ocfs2_ilookup(sb, blkno);
	/*
	 * If the inode exists in memory, we only need to check it's
	 * generation number
	 */
	if (inode)
		goto check_gen;

	/*
	 * This will synchronize us against ocfs2_delete_inode() on
	 * all nodes
	 */
	status = ocfs2_nfs_sync_lock(osb, 1);
	if (status < 0) {
		mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
		goto check_err;
	}

	status = ocfs2_test_inode_bit(osb, blkno, &set);
	if (status < 0) {
		if (status == -EINVAL) {
			/*
			 * The blkno NFS gave us doesn't even show up
			 * as an inode, we return -ESTALE to be
			 * nice
			 */
			mlog(0, "test inode bit failed %d\n", status);
			status = -ESTALE;
		} else {
			mlog(ML_ERROR, "test inode bit failed %d\n", status);
		}
		goto unlock_nfs_sync;
	}

	/* If the inode allocator bit is clear, this inode must be stale */
	if (!set) {
		mlog(0, "inode %llu suballoc bit is clear\n",
		     (unsigned long long)blkno);
		status = -ESTALE;
		goto unlock_nfs_sync;
	}

	inode = ocfs2_iget(osb, blkno, 0, 0);

unlock_nfs_sync:
	ocfs2_nfs_sync_unlock(osb, 1);

check_err:
	if (status < 0) {
		if (status == -ESTALE) {
			mlog(0, "stale inode ino: %llu generation: %u\n",
			     (unsigned long long)blkno, handle->ih_generation);
		}
		result = ERR_PTR(status);
		goto bail;
	}

	if (IS_ERR(inode)) {
		mlog_errno(PTR_ERR(inode));
		result = (void *)inode;
		goto bail;
	}

check_gen:
	if (handle->ih_generation != inode->i_generation) {
		iput(inode);
		mlog(0, "stale inode ino: %llu generation: %u\n",
		     (unsigned long long)blkno, handle->ih_generation);
		result = ERR_PTR(-ESTALE);
		goto bail;
	}

	result = d_obtain_alias(inode);
	if (!IS_ERR(result))
		result->d_op = &ocfs2_dentry_ops;
	else
		mlog_errno(PTR_ERR(result));

bail:
	mlog_exit_ptr(result);
	return result;
}