Commit 4d66952a authored by Al Viro's avatar Al Viro
Browse files

cifs: have cifs_fattr_to_inode() refuse to change type on live inode



... instead of trying to do that in the callers (and missing some,
at that)

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 3bcb39b0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -194,7 +194,7 @@ extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
				     struct cifs_sb_info *cifs_sb);
extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
					struct cifs_sb_info *);
extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
extern struct inode *cifs_iget(struct super_block *sb,
			       struct cifs_fattr *fattr);

+1 −1
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
			goto posix_open_ret;
		}
	} else {
		cifs_fattr_to_inode(*pinode, &fattr);
		rc = cifs_fattr_to_inode(*pinode, &fattr);
	}

posix_open_ret:
+15 −27
Original line number Diff line number Diff line
@@ -157,12 +157,18 @@ cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
}

/* populate an inode with info from a cifs_fattr struct */
void
int
cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
{
	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);

	if (!(inode->i_state & I_NEW) &&
	    unlikely(inode_wrong_type(inode, fattr->cf_mode))) {
		CIFS_I(inode)->time = 0; /* force reval */
		return -ESTALE;
	}

	cifs_revalidate_cache(inode, fattr);

	spin_lock(&inode->i_lock);
@@ -219,6 +225,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
		inode->i_flags |= S_AUTOMOUNT;
	if (inode->i_state & I_NEW)
		cifs_set_ops(inode);
	return 0;
}

void
@@ -363,7 +370,7 @@ cifs_get_file_info_unix(struct file *filp)
		rc = 0;
	}

	cifs_fattr_to_inode(inode, &fattr);
	rc = cifs_fattr_to_inode(inode, &fattr);
	free_xid(xid);
	return rc;
}
@@ -426,13 +433,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
		}

		/* if filetype is different, return error */
		if (unlikely(inode_wrong_type(*pinode, fattr.cf_mode))) {
			CIFS_I(*pinode)->time = 0; /* force reval */
			rc = -ESTALE;
			goto cgiiu_exit;
		}

		cifs_fattr_to_inode(*pinode, &fattr);
		rc = cifs_fattr_to_inode(*pinode, &fattr);
	}

cgiiu_exit:
@@ -782,7 +783,8 @@ cifs_get_file_info(struct file *filp)
	 */
	fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
	fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
	cifs_fattr_to_inode(inode, &fattr);
	/* if filetype is different, return error */
	rc = cifs_fattr_to_inode(inode, &fattr);
cgfi_exit:
	free_xid(xid);
	return rc;
@@ -1099,16 +1101,8 @@ cifs_get_inode_info(struct inode **inode,
			rc = -ESTALE;
			goto out;
		}

		/* if filetype is different, return error */
		if (unlikely(((*inode)->i_mode & S_IFMT) !=
		    (fattr.cf_mode & S_IFMT))) {
			CIFS_I(*inode)->time = 0; /* force reval */
			rc = -ESTALE;
			goto out;
		}

		cifs_fattr_to_inode(*inode, &fattr);
		rc = cifs_fattr_to_inode(*inode, &fattr);
	}
out:
	cifs_buf_release(smb1_backup_rsp_buf);
@@ -1214,14 +1208,7 @@ smb311_posix_get_inode_info(struct inode **inode,
		}

		/* if filetype is different, return error */
		if (unlikely(((*inode)->i_mode & S_IFMT) !=
		    (fattr.cf_mode & S_IFMT))) {
			CIFS_I(*inode)->time = 0; /* force reval */
			rc = -ESTALE;
			goto out;
		}

		cifs_fattr_to_inode(*inode, &fattr);
		rc = cifs_fattr_to_inode(*inode, &fattr);
	}
out:
	cifs_put_tlink(tlink);
@@ -1316,6 +1303,7 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
			}
		}

		/* can't fail - see cifs_find_inode() */
		cifs_fattr_to_inode(inode, fattr);
		if (sb->s_flags & SB_NOATIME)
			inode->i_flags |= S_NOATIME | S_NOCMTIME;
+1 −3
Original line number Diff line number Diff line
@@ -119,9 +119,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
			/* update inode in place
			 * if both i_ino and i_mode didn't change */
			if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid &&
			    (inode->i_mode & S_IFMT) ==
			    (fattr->cf_mode & S_IFMT)) {
				cifs_fattr_to_inode(inode, fattr);
			    cifs_fattr_to_inode(inode, fattr) == 0) {
				dput(dentry);
				return;
			}