Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c9cf98d authored by Martin Brandenburg's avatar Martin Brandenburg Committed by Mike Marshall
Browse files

orangefs: rename orangefs_inode_getattr to orangefs_inode_old_getattr



This is motivated by orangefs_inode_old_getattr's habit of writing over
live inodes.

Signed-off-by: default avatarMartin Brandenburg <martin@omnibond.com>
Signed-off-by: default avatarMike Marshall <hubcap@omnibond.com>
parent d57521a6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags)

	/* Now we must perform a getattr to validate the inode contents. */

	ret = orangefs_inode_getattr(dentry->d_inode,
	ret = orangefs_inode_old_getattr(dentry->d_inode,
	    ORANGEFS_ATTR_SYS_TYPE|ORANGEFS_ATTR_SYS_LNK_TARGET, 1);
	if (ret < 0) {
		gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d getattr failure.\n",
+4 −3
Original line number Diff line number Diff line
@@ -455,10 +455,10 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *ite

	/* Make sure generic_write_checks sees an up to date inode size. */
	if (file->f_flags & O_APPEND) {
		rc = orangefs_inode_getattr(file->f_mapping->host,
		rc = orangefs_inode_old_getattr(file->f_mapping->host,
					 ORANGEFS_ATTR_SYS_SIZE, 0);
		if (rc) {
			gossip_err("%s: orangefs_inode_getattr failed, rc:%zd:.\n",
			gossip_err("%s: orangefs_inode_old_getattr failed, rc:%zd:.\n",
				   __func__, rc);
			goto out;
		}
@@ -670,7 +670,8 @@ static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin)
		 * NOTE: We are only interested in file size here,
		 * so we set mask accordingly.
		 */
		ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_SIZE, 0);
		ret = orangefs_inode_old_getattr(inode,
		    ORANGEFS_ATTR_SYS_SIZE, 0);
		if (ret) {
			gossip_debug(GOSSIP_FILE_DEBUG,
				     "%s:%s:%d calling make bad inode\n",
+5 −4
Original line number Diff line number Diff line
@@ -268,7 +268,8 @@ int orangefs_getattr(struct vfsmount *mnt,
		     "orangefs_getattr: called on %s\n",
		     dentry->d_name.name);

	ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT, 0);
	ret = orangefs_inode_old_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT,
	    0);
	if (ret == 0) {
		generic_fillattr(inode, kstat);

@@ -299,7 +300,7 @@ int orangefs_permission(struct inode *inode, int mask)
	gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__);

	/* Make sure the permission (and other common attrs) are up to date. */
	ret = orangefs_inode_getattr(inode,
	ret = orangefs_inode_old_getattr(inode,
	    ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE, 0);
	if (ret < 0)
		return ret;
@@ -401,7 +402,7 @@ struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref
	if (!inode || !(inode->i_state & I_NEW))
		return inode;

	error = orangefs_inode_getattr(inode,
	error = orangefs_inode_old_getattr(inode,
	    ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE, 0);
	if (error) {
		iget_failed(inode);
@@ -447,7 +448,7 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
	orangefs_set_inode(inode, ref);
	inode->i_ino = hash;	/* needed for stat etc */

	error = orangefs_inode_getattr(inode,
	error = orangefs_inode_old_getattr(inode,
	    ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE, 0);
	if (error)
		goto out_iput;
+3 −1
Original line number Diff line number Diff line
@@ -544,7 +544,9 @@ int orangefs_inode_setxattr(struct inode *inode,
			 size_t size,
			 int flags);

int orangefs_inode_getattr(struct inode *inode, __u32 mask, int check);
int orangefs_inode_old_getattr(struct inode *inode, __u32 mask, int check);

int orangefs_inode_getattr(struct inode *inode, int new, int size);

int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr);

+120 −1
Original line number Diff line number Diff line
@@ -458,7 +458,8 @@ static int compare_attributes_to_inode(struct inode *inode,
 * otherwise. When check is 1, returns 1 on success where the inode is valid
 * and 0 on success where the inode is stale and -errno otherwise.
 */
int orangefs_inode_getattr(struct inode *inode, __u32 getattr_mask, int check)
int orangefs_inode_old_getattr(struct inode *inode, __u32 getattr_mask,
    int check)
{
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	struct orangefs_kernel_op_s *new_op;
@@ -536,6 +537,124 @@ int orangefs_inode_getattr(struct inode *inode, __u32 getattr_mask, int check)
	return ret;
}

static int orangefs_inode_type(enum orangefs_ds_type objtype)
{
	if (objtype == ORANGEFS_TYPE_METAFILE)
		return S_IFREG;
	else if (objtype == ORANGEFS_TYPE_DIRECTORY)
		return S_IFDIR;
	else if (objtype == ORANGEFS_TYPE_SYMLINK)
		return S_IFLNK;
	else
		return -1;
}

int orangefs_inode_getattr(struct inode *inode, int new, int size)
{
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	struct orangefs_kernel_op_s *new_op;
	loff_t inode_size, rounded_up_size;
	int ret;

	gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
	    get_khandle_from_ino(inode));

	new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
	if (!new_op)
		return -ENOMEM;
	new_op->upcall.req.getattr.refn = orangefs_inode->refn;
	new_op->upcall.req.getattr.mask = size ?
	    ORANGEFS_ATTR_SYS_ALL_NOHINT : ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE;

	ret = service_operation(new_op, __func__,
	    get_interruptible_flag(inode));
	if (ret != 0)
		goto out;

	ret = orangefs_inode_type(new_op->
	    downcall.resp.getattr.attributes.objtype);
	if (!new) {
		/*
		 * If the inode type or symlink target have changed then this
		 * inode is stale.
		 */
		if (ret == -1 || !(inode->i_mode & ret)) {
			orangefs_make_bad_inode(inode);
			ret = -ESTALE;
			goto out;
		}
		if (ret == S_IFLNK && strncmp(orangefs_inode->link_target,
		    new_op->downcall.resp.getattr.link_target,
		    ORANGEFS_NAME_MAX)) {
			orangefs_make_bad_inode(inode);
			ret = -ESTALE;
			goto out;
		}
	}

	switch (ret) {
	case S_IFREG:
		inode->i_flags = orangefs_inode_flags(&new_op->
		    downcall.resp.getattr.attributes);
		if (size) {
			inode_size = (loff_t)new_op->
			    downcall.resp.getattr.attributes.size;
			rounded_up_size =
			    (inode_size + (4096 - (inode_size % 4096)));
			inode->i_size = inode_size;
			orangefs_inode->blksize =
			    new_op->downcall.resp.getattr.attributes.blksize;
			spin_lock(&inode->i_lock);
			inode->i_bytes = inode_size;
			inode->i_blocks =
			    (unsigned long)(rounded_up_size / 512);
			spin_unlock(&inode->i_lock);
		}
		break;
	case S_IFDIR:
		inode->i_size = PAGE_CACHE_SIZE;
		orangefs_inode->blksize = (1 << inode->i_blkbits);
		spin_lock(&inode->i_lock);
		inode_set_bytes(inode, inode->i_size);
		spin_unlock(&inode->i_lock);
		set_nlink(inode, 1);
		break;
	case S_IFLNK:
		if (new) {
			inode->i_size = (loff_t)strlen(new_op->
			    downcall.resp.getattr.link_target);
			orangefs_inode->blksize = (1 << inode->i_blkbits);
			strlcpy(orangefs_inode->link_target,
			    new_op->downcall.resp.getattr.link_target,
			    ORANGEFS_NAME_MAX);
		}
		break;
	}

	inode->i_uid = make_kuid(&init_user_ns, new_op->
	    downcall.resp.getattr.attributes.owner);
	inode->i_gid = make_kgid(&init_user_ns, new_op->
	    downcall.resp.getattr.attributes.group);
	inode->i_atime.tv_sec = (time64_t)new_op->
	    downcall.resp.getattr.attributes.atime;
	inode->i_mtime.tv_sec = (time64_t)new_op->
	    downcall.resp.getattr.attributes.mtime;
	inode->i_ctime.tv_sec = (time64_t)new_op->
	    downcall.resp.getattr.attributes.ctime;
	inode->i_atime.tv_nsec = 0;
	inode->i_mtime.tv_nsec = 0;
	inode->i_ctime.tv_nsec = 0;

	/* special case: mark the root inode as sticky */
	inode->i_mode = ret | (is_root_handle(inode) ? S_ISVTX : 0) |
	    orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);

	ret = 0;
out:
	op_release(new_op);
	return ret;
}

/*
 * issues a orangefs setattr request to make sure the new attribute values
 * take effect if successful.  returns 0 on success; -errno otherwise