예제 #1
0
파일: namei.c 프로젝트: Goon83/SALB
static int pvfs2_rmdir(
    struct inode *dir,
    struct dentry *dentry)
{
    int ret = -ENOTEMPTY;
    struct inode *inode = dentry->d_inode;

    ret = pvfs2_unlink(dir, dentry);
    if (ret == 0)
    {
        pvfs2_inode_t *dir_pinode = PVFS2_I(dir);
        inode->i_nlink--; 
#if 0
        /* NOTE: we have no good way to keep nlink consistent for directories
         * across clients; keep constant at 1  -Phil
         */
	dir->i_nlink--;
#endif

        SetMtimeFlag(dir_pinode);
        pvfs2_update_inode_time(dir);
        mark_inode_dirty_sync(dir);
    }
    return ret;
}
예제 #2
0
파일: namei.c 프로젝트: Goon83/SALB
static int pvfs2_mkdir(
    struct inode *dir,
    struct dentry *dentry,
    int mode)
{
    int ret = -EINVAL;
    struct inode *inode = NULL;

    inode = pvfs2_create_entry(
        dir, dentry, NULL, mode, PVFS2_VFS_OP_MKDIR, &ret);

    if (inode)
    {
#if 0
        /* NOTE: we have no good way to keep nlink consistent for directories
         * across clients; keep constant at 1  -Phil
         */
	dir->i_nlink++;
#endif
        pvfs2_inode_t *dir_pinode = PVFS2_I(dir);

        SetMtimeFlag(dir_pinode);
        pvfs2_update_inode_time(dir);
        mark_inode_dirty_sync(dir);

	ret = 0;
    }
    return ret;
}
예제 #3
0
파일: namei.c 프로젝트: Goon83/SALB
static int pvfs2_symlink(
    struct inode *dir,
    struct dentry *dentry,
    const char *symname)
{
    int ret = -EINVAL, mode = 755;
    struct inode *inode = NULL;

    gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_symlink: called\n");

    inode = pvfs2_create_entry(
        dir, dentry, symname, mode, PVFS2_VFS_OP_SYMLINK, &ret);

    if (inode)
    {
        pvfs2_inode_t *dir_pinode = PVFS2_I(dir);

        SetMtimeFlag(dir_pinode);
        pvfs2_update_inode_time(dir);
        mark_inode_dirty_sync(dir);

        ret = 0;
    }
    return ret;
}
예제 #4
0
파일: namei.c 프로젝트: Goon83/SALB
static int pvfs2_create(
    struct inode *dir,
    struct dentry *dentry,
    int mode,
    struct nameidata *nd)
#endif
{
    int ret = -EINVAL;
    struct inode *inode = NULL;

    gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_create: called\n");

    inode = pvfs2_create_entry(
        dir, dentry, NULL, mode, PVFS2_VFS_OP_CREATE, &ret);

    if (inode)
    {
        pvfs2_inode_t *dir_pinode = PVFS2_I(dir);

        SetMtimeFlag(dir_pinode);
        pvfs2_update_inode_time(dir);
        mark_inode_dirty_sync(dir);
        
        ret = 0;
    }

    gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_create: returning %d\n", ret);
    return ret;
}
예제 #5
0
파일: namei.c 프로젝트: AK101111/linux
/* return 0 on success; non-zero otherwise */
static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	int ret;

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "%s: called on %s\n"
		     "  (inode %pU): Parent is %pU | fs_id %d\n",
		     __func__,
		     dentry->d_name.name,
		     get_khandle_from_ino(inode),
		     &parent->refn.khandle,
		     parent->refn.fs_id);

	new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE);
	if (!new_op)
		return -ENOMEM;

	new_op->upcall.req.remove.parent_refn = parent->refn;
	strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name,
		ORANGEFS_NAME_MAX);

	ret = service_operation(new_op, "orangefs_unlink",
				get_interruptible_flag(inode));

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "%s: service_operation returned:%d:\n",
		     __func__,
		     ret);

	op_release(new_op);

	if (!ret) {
		drop_nlink(inode);

		SetMtimeFlag(parent);
		dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
		mark_inode_dirty_sync(dir);
	}
	return ret;
}
예제 #6
0
파일: inode.c 프로젝트: sumitn/pvfs
/** Change size of an object referenced by inode
 */
void pvfs2_truncate(struct inode *inode)
{
    loff_t orig_size = pvfs2_i_size_read(inode);

    if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
        return;
    gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2: pvfs2_truncate called on inode %llu "
                "with size %ld\n", llu(get_handle_from_ino(inode)), (long) orig_size);

    /* successful truncate when size changes also requires mtime updates 
     * although the mtime updates are propagated lazily!
     */
    if (pvfs2_truncate_inode(inode, inode->i_size) == 0
            && (orig_size != pvfs2_i_size_read(inode)))
    {
        pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
        SetMtimeFlag(pvfs2_inode);
        inode->i_mtime = CURRENT_TIME;
        mark_inode_dirty_sync(inode);
    }
}
예제 #7
0
파일: namei.c 프로젝트: Goon83/SALB
/* return 0 on success; non-zero otherwise */
static int pvfs2_unlink(
    struct inode *dir,
    struct dentry *dentry)
{
    int ret = -ENOENT;
    struct inode *inode = dentry->d_inode;

    gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_unlink: pvfs2_unlink called on %s\n",
                dentry->d_name.name);

    ret = pvfs2_remove_entry(dir, dentry);
    if (ret == 0)
    {
        pvfs2_inode_t *dir_pinode = PVFS2_I(dir);
        inode->i_nlink--;

        SetMtimeFlag(dir_pinode);
        pvfs2_update_inode_time(dir);
        mark_inode_dirty_sync(dir);
    }
    return ret;
}
예제 #8
0
파일: namei.c 프로젝트: AK101111/linux
static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	struct inode *inode;
	int ret;

	new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR);
	if (!new_op)
		return -ENOMEM;

	new_op->upcall.req.mkdir.parent_refn = parent->refn;

	fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes,
			      ORANGEFS_TYPE_DIRECTORY, mode);

	strncpy(new_op->upcall.req.mkdir.d_name,
		dentry->d_name.name, ORANGEFS_NAME_MAX);

	ret = service_operation(new_op, __func__, get_interruptible_flag(dir));

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "Mkdir Got ORANGEFS handle %pU on fsid %d\n",
		     &new_op->downcall.resp.mkdir.refn.khandle,
		     new_op->downcall.resp.mkdir.refn.fs_id);

	if (ret < 0) {
		gossip_debug(GOSSIP_NAME_DEBUG,
			     "%s: failed with error code %d\n",
			     __func__, ret);
		goto out;
	}

	inode = orangefs_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0,
				&new_op->downcall.resp.mkdir.refn);
	if (IS_ERR(inode)) {
		gossip_err("*** Failed to allocate orangefs dir inode\n");
		ret = PTR_ERR(inode);
		goto out;
	}

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "Assigned dir inode new number of %pU\n",
		     get_khandle_from_ino(inode));

	d_instantiate(dentry, inode);
	unlock_new_inode(inode);
	dentry->d_time = jiffies + dcache_timeout_msecs*HZ/1000;
	ORANGEFS_I(inode)->getattr_time = jiffies - 1;

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "Inode (Directory) %pU -> %s\n",
		     get_khandle_from_ino(inode),
		     dentry->d_name.name);

	/*
	 * NOTE: we have no good way to keep nlink consistent for directories
	 * across clients; keep constant at 1.
	 */
	SetMtimeFlag(parent);
	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
	mark_inode_dirty_sync(dir);
out:
	op_release(new_op);
	return ret;
}
예제 #9
0
파일: namei.c 프로젝트: AK101111/linux
static int orangefs_symlink(struct inode *dir,
			 struct dentry *dentry,
			 const char *symname)
{
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	struct inode *inode;
	int mode = 755;
	int ret;

	gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__);

	if (!symname)
		return -EINVAL;

	if (strlen(symname)+1 > ORANGEFS_NAME_MAX)
		return -ENAMETOOLONG;

	new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK);
	if (!new_op)
		return -ENOMEM;

	new_op->upcall.req.sym.parent_refn = parent->refn;

	fill_default_sys_attrs(new_op->upcall.req.sym.attributes,
			       ORANGEFS_TYPE_SYMLINK,
			       mode);

	strncpy(new_op->upcall.req.sym.entry_name,
		dentry->d_name.name,
		ORANGEFS_NAME_MAX);
	strncpy(new_op->upcall.req.sym.target, symname, ORANGEFS_NAME_MAX);

	ret = service_operation(new_op, __func__, get_interruptible_flag(dir));

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "Symlink Got ORANGEFS handle %pU on fsid %d (ret=%d)\n",
		     &new_op->downcall.resp.sym.refn.khandle,
		     new_op->downcall.resp.sym.refn.fs_id, ret);

	if (ret < 0) {
		gossip_debug(GOSSIP_NAME_DEBUG,
			    "%s: failed with error code %d\n",
			    __func__, ret);
		goto out;
	}

	inode = orangefs_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0,
				&new_op->downcall.resp.sym.refn);
	if (IS_ERR(inode)) {
		gossip_err
		    ("*** Failed to allocate orangefs symlink inode\n");
		ret = PTR_ERR(inode);
		goto out;
	}

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "Assigned symlink inode new number of %pU\n",
		     get_khandle_from_ino(inode));

	d_instantiate(dentry, inode);
	unlock_new_inode(inode);
	dentry->d_time = jiffies + dcache_timeout_msecs*HZ/1000;
	ORANGEFS_I(inode)->getattr_time = jiffies - 1;

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "Inode (Symlink) %pU -> %s\n",
		     get_khandle_from_ino(inode),
		     dentry->d_name.name);

	SetMtimeFlag(parent);
	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
	mark_inode_dirty_sync(dir);
	ret = 0;
out:
	op_release(new_op);
	return ret;
}
예제 #10
0
파일: namei.c 프로젝트: AK101111/linux
/*
 * Get a newly allocated inode to go with a negative dentry.
 */
static int orangefs_create(struct inode *dir,
			struct dentry *dentry,
			umode_t mode,
			bool exclusive)
{
	struct orangefs_inode_s *parent = ORANGEFS_I(dir);
	struct orangefs_kernel_op_s *new_op;
	struct inode *inode;
	int ret;

	gossip_debug(GOSSIP_NAME_DEBUG, "%s: %s\n",
		     __func__,
		     dentry->d_name.name);

	new_op = op_alloc(ORANGEFS_VFS_OP_CREATE);
	if (!new_op)
		return -ENOMEM;

	new_op->upcall.req.create.parent_refn = parent->refn;

	fill_default_sys_attrs(new_op->upcall.req.create.attributes,
			       ORANGEFS_TYPE_METAFILE, mode);

	strncpy(new_op->upcall.req.create.d_name,
		dentry->d_name.name, ORANGEFS_NAME_MAX);

	ret = service_operation(new_op, __func__, get_interruptible_flag(dir));

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "%s: %s: handle:%pU: fsid:%d: new_op:%p: ret:%d:\n",
		     __func__,
		     dentry->d_name.name,
		     &new_op->downcall.resp.create.refn.khandle,
		     new_op->downcall.resp.create.refn.fs_id,
		     new_op,
		     ret);

	if (ret < 0)
		goto out;

	inode = orangefs_new_inode(dir->i_sb, dir, S_IFREG | mode, 0,
				&new_op->downcall.resp.create.refn);
	if (IS_ERR(inode)) {
		gossip_err("%s: Failed to allocate inode for file :%s:\n",
			   __func__,
			   dentry->d_name.name);
		ret = PTR_ERR(inode);
		goto out;
	}

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "%s: Assigned inode :%pU: for file :%s:\n",
		     __func__,
		     get_khandle_from_ino(inode),
		     dentry->d_name.name);

	d_instantiate(dentry, inode);
	unlock_new_inode(inode);
	dentry->d_time = jiffies + dcache_timeout_msecs*HZ/1000;
	ORANGEFS_I(inode)->getattr_time = jiffies - 1;

	gossip_debug(GOSSIP_NAME_DEBUG,
		     "%s: dentry instantiated for %s\n",
		     __func__,
		     dentry->d_name.name);

	SetMtimeFlag(parent);
	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
	mark_inode_dirty_sync(dir);
	ret = 0;
out:
	op_release(new_op);
	gossip_debug(GOSSIP_NAME_DEBUG,
		     "%s: %s: returning %d\n",
		     __func__,
		     dentry->d_name.name,
		     ret);
	return ret;
}
예제 #11
0
파일: file.c 프로젝트: 513855417/linux
/*
 * Common entry point for read/write/readv/writev
 * This function will dispatch it to either the direct I/O
 * or buffered I/O path depending on the mount options and/or
 * augmented/extended metadata attached to the file.
 * Note: File extended attributes override any mount options.
 */
static ssize_t do_readv_writev(enum ORANGEFS_io_type type, struct file *file,
		loff_t *offset, struct iov_iter *iter)
{
	struct inode *inode = file->f_mapping->host;
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	struct orangefs_khandle *handle = &orangefs_inode->refn.khandle;
	size_t count = iov_iter_count(iter);
	ssize_t total_count = 0;
	ssize_t ret = -EINVAL;

	gossip_debug(GOSSIP_FILE_DEBUG,
		"%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n",
		__func__,
		handle,
		(int)count);

	if (type == ORANGEFS_IO_WRITE) {
		gossip_debug(GOSSIP_FILE_DEBUG,
			     "%s(%pU): proceeding with offset : %llu, "
			     "size %d\n",
			     __func__,
			     handle,
			     llu(*offset),
			     (int)count);
	}

	if (count == 0) {
		ret = 0;
		goto out;
	}

	while (iov_iter_count(iter)) {
		size_t each_count = iov_iter_count(iter);
		size_t amt_complete;

		/* how much to transfer in this loop iteration */
		if (each_count > orangefs_bufmap_size_query())
			each_count = orangefs_bufmap_size_query();

		gossip_debug(GOSSIP_FILE_DEBUG,
			     "%s(%pU): size of each_count(%d)\n",
			     __func__,
			     handle,
			     (int)each_count);
		gossip_debug(GOSSIP_FILE_DEBUG,
			     "%s(%pU): BEFORE wait_for_io: offset is %d\n",
			     __func__,
			     handle,
			     (int)*offset);

		ret = wait_for_direct_io(type, inode, offset, iter,
				each_count, 0);
		gossip_debug(GOSSIP_FILE_DEBUG,
			     "%s(%pU): return from wait_for_io:%d\n",
			     __func__,
			     handle,
			     (int)ret);

		if (ret < 0)
			goto out;

		*offset += ret;
		total_count += ret;
		amt_complete = ret;

		gossip_debug(GOSSIP_FILE_DEBUG,
			     "%s(%pU): AFTER wait_for_io: offset is %d\n",
			     __func__,
			     handle,
			     (int)*offset);

		/*
		 * if we got a short I/O operations,
		 * fall out and return what we got so far
		 */
		if (amt_complete < each_count)
			break;
	} /*end while */

out:
	if (total_count > 0)
		ret = total_count;
	if (ret > 0) {
		if (type == ORANGEFS_IO_READ) {
			file_accessed(file);
		} else {
			SetMtimeFlag(orangefs_inode);
			inode->i_mtime = CURRENT_TIME;
			mark_inode_dirty_sync(inode);
		}
	}

	gossip_debug(GOSSIP_FILE_DEBUG,
		     "%s(%pU): Value(%d) returned.\n",
		     __func__,
		     handle,
		     (int)ret);

	return ret;
}