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

Commit 132ac7b7 authored by Jeff Layton's avatar Jeff Layton Committed by Steve French
Browse files

cifs: refactor new_inode() calls and inode initialization



Move new inode creation into a separate routine and refactor the
callers to take advantage of it.

Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent e4cce94c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ extern u64 cifs_UnixTimeToNT(struct timespec);
extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);

extern struct inode *cifs_new_inode(struct super_block *sb,
				    unsigned long *inum);
extern int cifs_get_inode_info(struct inode **pinode,
			const unsigned char *search_path,
			FILE_ALL_INFO *pfile_info,
+60 −36
Original line number Diff line number Diff line
@@ -199,6 +199,49 @@ static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat,
	pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
}

/**
 * cifs_new inode - create new inode, initialize, and hash it
 * @sb - pointer to superblock
 * @inum - if valid pointer and serverino is enabled, replace i_ino with val
 *
 * Create a new inode, initialize it for CIFS and hash it. Returns the new
 * inode or NULL if one couldn't be allocated.
 *
 * If the share isn't mounted with "serverino" or inum is a NULL pointer then
 * we'll just use the inode number assigned by new_inode(). Note that this can
 * mean i_ino collisions since the i_ino assigned by new_inode is not
 * guaranteed to be unique.
 */
struct inode *
cifs_new_inode(struct super_block *sb, unsigned long *inum)
{
	struct inode *inode;

	inode = new_inode(sb);
	if (inode == NULL)
		return NULL;

	/*
	 * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we
	 *     stop passing inum as ptr. Are there sanity checks we can use to
	 *     ensure that the server is really filling in that field? Also,
	 *     if serverino is disabled, perhaps we should be using iunique()?
	 */
	if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
		inode->i_ino = *inum;

	/*
	 * must set this here instead of cifs_alloc_inode since VFS will
	 * clobber i_flags
	 */
	if (sb->s_flags & MS_NOATIME)
		inode->i_flags |= S_NOATIME | S_NOCMTIME;

	insert_inode_hash(inode);

	return inode;
}

int cifs_get_inode_info_unix(struct inode **pinode,
	const unsigned char *full_path, struct super_block *sb, int xid)
{
@@ -233,22 +276,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,

	/* get new inode */
	if (*pinode == NULL) {
		*pinode = new_inode(sb);
		*pinode = cifs_new_inode(sb, (unsigned long *)
						&find_data.UniqueId);
		if (*pinode == NULL) {
			rc = -ENOMEM;
			goto cgiiu_exit;
		}
		/* Is an i_ino of zero legal? */
		/* note ino incremented to unique num in new_inode */
		/* Are there sanity checks we can use to ensure that
		   the server is really filling in that field? */
		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
			(*pinode)->i_ino = (unsigned long)find_data.UniqueId;

		if (sb->s_flags & MS_NOATIME)
			(*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;

		insert_inode_hash(*pinode);
	}

	inode = *pinode;
@@ -465,11 +498,8 @@ int cifs_get_inode_info(struct inode **pinode,

	/* get new inode */
	if (*pinode == NULL) {
		*pinode = new_inode(sb);
		if (*pinode == NULL) {
			rc = -ENOMEM;
			goto cgii_exit;
		}
		__u64 inode_num;

		/* Is an i_ino of zero legal? Can we use that to check
		   if the server supports returning inode numbers?  Are
		   there other sanity checks we can use to ensure that
@@ -486,7 +516,6 @@ int cifs_get_inode_info(struct inode **pinode,

		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
			int rc1 = 0;
			__u64 inode_num;

			rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
					full_path, &inode_num,
@@ -496,12 +525,17 @@ int cifs_get_inode_info(struct inode **pinode,
			if (rc1) {
				cFYI(1, ("GetSrvInodeNum rc %d", rc1));
				/* BB EOPNOSUPP disable SERVER_INUM? */
			} else /* do we need cast or hash to ino? */
				(*pinode)->i_ino = inode_num;
		} /* else ino incremented to unique num in new_inode*/
		if (sb->s_flags & MS_NOATIME)
			(*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
		insert_inode_hash(*pinode);
			}
			*pinode = cifs_new_inode(sb, (unsigned long *)
							&inode_num);
		} else {
			*pinode = cifs_new_inode(sb, NULL);
		}

		if (*pinode == NULL) {
			rc = -ENOMEM;
			goto cgii_exit;
		}
	}
	inode = *pinode;
	cifsInfo = CIFS_I(inode);
@@ -1114,24 +1148,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
			else
				direntry->d_op = &cifs_dentry_ops;

			newinode = new_inode(inode->i_sb);
			newinode = cifs_new_inode(inode->i_sb, (unsigned long *)
							&pInfo->UniqueId);
			if (newinode == NULL) {
				kfree(pInfo);
				goto mkdir_get_info;
			}

			/* Is an i_ino of zero legal? */
			/* Are there sanity checks we can use to ensure that
			   the server is really filling in that field? */
			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
				newinode->i_ino =
					(unsigned long)pInfo->UniqueId;
			} /* note ino incremented to unique num in new_inode */
			if (inode->i_sb->s_flags & MS_NOATIME)
				newinode->i_flags |= S_NOATIME | S_NOCMTIME;
			newinode->i_nlink = 2;

			insert_inode_hash(newinode);
			d_instantiate(direntry, newinode);

			/* we already checked in POSIXCreate whether
+24 −30
Original line number Diff line number Diff line
@@ -56,35 +56,34 @@ static inline void dump_cifs_file_struct(struct file *file, char *label)
}
#endif /* DEBUG2 */

/* Returns one if new inode created (which therefore needs to be hashed) */
/* Returns 1 if new inode created, 2 if both dentry and inode were */
/* Might check in the future if inode number changed so we can rehash inode */
static int construct_dentry(struct qstr *qstring, struct file *file,
	struct inode **ptmp_inode, struct dentry **pnew_dentry)
static int
construct_dentry(struct qstr *qstring, struct file *file,
		 struct inode **ptmp_inode, struct dentry **pnew_dentry,
		 unsigned long *inum)
{
	struct dentry *tmp_dentry;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *pTcon;
	struct dentry *tmp_dentry = NULL;
	struct super_block *sb = file->f_path.dentry->d_sb;
	int rc = 0;

	cFYI(1, ("For %s", qstring->name));
	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
	pTcon = cifs_sb->tcon;

	qstring->hash = full_name_hash(qstring->name, qstring->len);
	tmp_dentry = d_lookup(file->f_path.dentry, qstring);
	if (tmp_dentry) {
		/* BB: overwrite old name? i.e. tmp_dentry->d_name and
		 * tmp_dentry->d_name.len??
		 */
		cFYI(0, ("existing dentry with inode 0x%p",
			 tmp_dentry->d_inode));
		*ptmp_inode = tmp_dentry->d_inode;
/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/
		if (*ptmp_inode == NULL) {
			*ptmp_inode = new_inode(file->f_path.dentry->d_sb);
			*ptmp_inode = cifs_new_inode(sb, inum);
			if (*ptmp_inode == NULL)
				return rc;
			rc = 1;
		}
		if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
			(*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
	} else {
		tmp_dentry = d_alloc(file->f_path.dentry, qstring);
		if (tmp_dentry == NULL) {
@@ -93,15 +92,14 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
			return rc;
		}

		*ptmp_inode = new_inode(file->f_path.dentry->d_sb);
		if (pTcon->nocase)
		if (CIFS_SB(sb)->tcon->nocase)
			tmp_dentry->d_op = &cifs_ci_dentry_ops;
		else
			tmp_dentry->d_op = &cifs_dentry_ops;

		*ptmp_inode = cifs_new_inode(sb, inum);
		if (*ptmp_inode == NULL)
			return rc;
		if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME)
			(*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME;
		rc = 2;
	}

@@ -842,8 +840,6 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
			len = strnlen(filename, PATH_MAX);
		}

		/* BB fixme - hash low and high 32 bits if not 64 bit arch BB */
		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
		*pinum = pFindData->UniqueId;
	} else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
		FILE_DIRECTORY_INFO *pFindData =
@@ -940,20 +936,18 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
	if (rc)
		return rc;

	rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry);
	/* only these two infolevels return valid inode numbers */
	if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX ||
	    pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO)
		rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry,
					&inum);
	else
		rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry,
					NULL);

	if ((tmp_inode == NULL) || (tmp_dentry == NULL))
		return -ENOMEM;

	if (rc) {
		/* inode created, we need to hash it with right inode number */
		if (inum != 0) {
			/* BB fixme - hash the 2 32 quantities bits together if
			 *  necessary BB */
			tmp_inode->i_ino = inum;
		}
		insert_inode_hash(tmp_inode);
	}

	/* we pass in rc below, indicating whether it is a new inode,
	   so we can figure out whether to invalidate the inode cached
	   data if the file has changed */