Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>

authored by

Jeff Layton and committed by
Steve French
132ac7b7 e4cce94c

+86 -66
+2
fs/cifs/cifsproto.h
··· 92 92 extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); 93 93 extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); 94 94 95 + extern struct inode *cifs_new_inode(struct super_block *sb, 96 + unsigned long *inum); 95 97 extern int cifs_get_inode_info(struct inode **pinode, 96 98 const unsigned char *search_path, 97 99 FILE_ALL_INFO *pfile_info,
+60 -36
fs/cifs/inode.c
··· 199 199 pfnd_dat->Gid = cpu_to_le64(pinode->i_gid); 200 200 } 201 201 202 + /** 203 + * cifs_new inode - create new inode, initialize, and hash it 204 + * @sb - pointer to superblock 205 + * @inum - if valid pointer and serverino is enabled, replace i_ino with val 206 + * 207 + * Create a new inode, initialize it for CIFS and hash it. Returns the new 208 + * inode or NULL if one couldn't be allocated. 209 + * 210 + * If the share isn't mounted with "serverino" or inum is a NULL pointer then 211 + * we'll just use the inode number assigned by new_inode(). Note that this can 212 + * mean i_ino collisions since the i_ino assigned by new_inode is not 213 + * guaranteed to be unique. 214 + */ 215 + struct inode * 216 + cifs_new_inode(struct super_block *sb, unsigned long *inum) 217 + { 218 + struct inode *inode; 219 + 220 + inode = new_inode(sb); 221 + if (inode == NULL) 222 + return NULL; 223 + 224 + /* 225 + * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we 226 + * stop passing inum as ptr. Are there sanity checks we can use to 227 + * ensure that the server is really filling in that field? Also, 228 + * if serverino is disabled, perhaps we should be using iunique()? 229 + */ 230 + if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) 231 + inode->i_ino = *inum; 232 + 233 + /* 234 + * must set this here instead of cifs_alloc_inode since VFS will 235 + * clobber i_flags 236 + */ 237 + if (sb->s_flags & MS_NOATIME) 238 + inode->i_flags |= S_NOATIME | S_NOCMTIME; 239 + 240 + insert_inode_hash(inode); 241 + 242 + return inode; 243 + } 244 + 202 245 int cifs_get_inode_info_unix(struct inode **pinode, 203 246 const unsigned char *full_path, struct super_block *sb, int xid) 204 247 { ··· 276 233 277 234 /* get new inode */ 278 235 if (*pinode == NULL) { 279 - *pinode = new_inode(sb); 236 + *pinode = cifs_new_inode(sb, (unsigned long *) 237 + &find_data.UniqueId); 280 238 if (*pinode == NULL) { 281 239 rc = -ENOMEM; 282 240 goto cgiiu_exit; 283 241 } 284 - /* Is an i_ino of zero legal? */ 285 - /* note ino incremented to unique num in new_inode */ 286 - /* Are there sanity checks we can use to ensure that 287 - the server is really filling in that field? */ 288 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 289 - (*pinode)->i_ino = (unsigned long)find_data.UniqueId; 290 - 291 - if (sb->s_flags & MS_NOATIME) 292 - (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 293 - 294 - insert_inode_hash(*pinode); 295 242 } 296 243 297 244 inode = *pinode; ··· 498 465 499 466 /* get new inode */ 500 467 if (*pinode == NULL) { 501 - *pinode = new_inode(sb); 502 - if (*pinode == NULL) { 503 - rc = -ENOMEM; 504 - goto cgii_exit; 505 - } 468 + __u64 inode_num; 469 + 506 470 /* Is an i_ino of zero legal? Can we use that to check 507 471 if the server supports returning inode numbers? Are 508 472 there other sanity checks we can use to ensure that ··· 516 486 517 487 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 518 488 int rc1 = 0; 519 - __u64 inode_num; 520 489 521 490 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 522 491 full_path, &inode_num, ··· 525 496 if (rc1) { 526 497 cFYI(1, ("GetSrvInodeNum rc %d", rc1)); 527 498 /* BB EOPNOSUPP disable SERVER_INUM? */ 528 - } else /* do we need cast or hash to ino? */ 529 - (*pinode)->i_ino = inode_num; 530 - } /* else ino incremented to unique num in new_inode*/ 531 - if (sb->s_flags & MS_NOATIME) 532 - (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; 533 - insert_inode_hash(*pinode); 499 + } 500 + *pinode = cifs_new_inode(sb, (unsigned long *) 501 + &inode_num); 502 + } else { 503 + *pinode = cifs_new_inode(sb, NULL); 504 + } 505 + 506 + if (*pinode == NULL) { 507 + rc = -ENOMEM; 508 + goto cgii_exit; 509 + } 534 510 } 535 511 inode = *pinode; 536 512 cifsInfo = CIFS_I(inode); ··· 1148 1114 else 1149 1115 direntry->d_op = &cifs_dentry_ops; 1150 1116 1151 - newinode = new_inode(inode->i_sb); 1117 + newinode = cifs_new_inode(inode->i_sb, (unsigned long *) 1118 + &pInfo->UniqueId); 1152 1119 if (newinode == NULL) { 1153 1120 kfree(pInfo); 1154 1121 goto mkdir_get_info; 1155 1122 } 1156 1123 1157 - /* Is an i_ino of zero legal? */ 1158 - /* Are there sanity checks we can use to ensure that 1159 - the server is really filling in that field? */ 1160 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 1161 - newinode->i_ino = 1162 - (unsigned long)pInfo->UniqueId; 1163 - } /* note ino incremented to unique num in new_inode */ 1164 - if (inode->i_sb->s_flags & MS_NOATIME) 1165 - newinode->i_flags |= S_NOATIME | S_NOCMTIME; 1166 1124 newinode->i_nlink = 2; 1167 - 1168 - insert_inode_hash(newinode); 1169 1125 d_instantiate(direntry, newinode); 1170 1126 1171 1127 /* we already checked in POSIXCreate whether
+24 -30
fs/cifs/readdir.c
··· 56 56 } 57 57 #endif /* DEBUG2 */ 58 58 59 - /* Returns one if new inode created (which therefore needs to be hashed) */ 59 + /* Returns 1 if new inode created, 2 if both dentry and inode were */ 60 60 /* Might check in the future if inode number changed so we can rehash inode */ 61 - static int construct_dentry(struct qstr *qstring, struct file *file, 62 - struct inode **ptmp_inode, struct dentry **pnew_dentry) 61 + static int 62 + construct_dentry(struct qstr *qstring, struct file *file, 63 + struct inode **ptmp_inode, struct dentry **pnew_dentry, 64 + unsigned long *inum) 63 65 { 64 - struct dentry *tmp_dentry; 65 - struct cifs_sb_info *cifs_sb; 66 - struct cifsTconInfo *pTcon; 66 + struct dentry *tmp_dentry = NULL; 67 + struct super_block *sb = file->f_path.dentry->d_sb; 67 68 int rc = 0; 68 69 69 70 cFYI(1, ("For %s", qstring->name)); 70 - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 71 - pTcon = cifs_sb->tcon; 72 71 73 72 qstring->hash = full_name_hash(qstring->name, qstring->len); 74 73 tmp_dentry = d_lookup(file->f_path.dentry, qstring); 75 74 if (tmp_dentry) { 75 + /* BB: overwrite old name? i.e. tmp_dentry->d_name and 76 + * tmp_dentry->d_name.len?? 77 + */ 76 78 cFYI(0, ("existing dentry with inode 0x%p", 77 79 tmp_dentry->d_inode)); 78 80 *ptmp_inode = tmp_dentry->d_inode; 79 - /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ 80 81 if (*ptmp_inode == NULL) { 81 - *ptmp_inode = new_inode(file->f_path.dentry->d_sb); 82 + *ptmp_inode = cifs_new_inode(sb, inum); 82 83 if (*ptmp_inode == NULL) 83 84 return rc; 84 85 rc = 1; 85 86 } 86 - if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 87 - (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 88 87 } else { 89 88 tmp_dentry = d_alloc(file->f_path.dentry, qstring); 90 89 if (tmp_dentry == NULL) { ··· 92 93 return rc; 93 94 } 94 95 95 - *ptmp_inode = new_inode(file->f_path.dentry->d_sb); 96 - if (pTcon->nocase) 96 + if (CIFS_SB(sb)->tcon->nocase) 97 97 tmp_dentry->d_op = &cifs_ci_dentry_ops; 98 98 else 99 99 tmp_dentry->d_op = &cifs_dentry_ops; 100 + 101 + *ptmp_inode = cifs_new_inode(sb, inum); 100 102 if (*ptmp_inode == NULL) 101 103 return rc; 102 - if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) 103 - (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; 104 104 rc = 2; 105 105 } 106 106 ··· 840 842 len = strnlen(filename, PATH_MAX); 841 843 } 842 844 843 - /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */ 844 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 845 - *pinum = pFindData->UniqueId; 845 + *pinum = pFindData->UniqueId; 846 846 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 847 847 FILE_DIRECTORY_INFO *pFindData = 848 848 (FILE_DIRECTORY_INFO *)current_entry; ··· 936 940 if (rc) 937 941 return rc; 938 942 939 - rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry); 943 + /* only these two infolevels return valid inode numbers */ 944 + if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || 945 + pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) 946 + rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, 947 + &inum); 948 + else 949 + rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, 950 + NULL); 951 + 940 952 if ((tmp_inode == NULL) || (tmp_dentry == NULL)) 941 953 return -ENOMEM; 942 - 943 - if (rc) { 944 - /* inode created, we need to hash it with right inode number */ 945 - if (inum != 0) { 946 - /* BB fixme - hash the 2 32 quantities bits together if 947 - * necessary BB */ 948 - tmp_inode->i_ino = inum; 949 - } 950 - insert_inode_hash(tmp_inode); 951 - } 952 954 953 955 /* we pass in rc below, indicating whether it is a new inode, 954 956 so we can figure out whether to invalidate the inode cached