History

cifs: fix inode leak in cifs_get_inode_info_unix

Try this: mount a share with unix extensions create a file on it umount the share You'll get the following message in the ring buffer: VFS: Busy inodes after unmount of cifs. Self-destruct in 5 seconds. Have a nice day... ...the problem is that cifs_get_inode_info_unix is creating and hashing a new inode even when it's going to return error anyway. The first lookup when creating a file returns an error so we end up leaking this inode before we do the actual create. This appears to be a regression caused by commit 0e4bbde94fdc33f5b3d793166b21bf768ca3e098. The following patch seems to fix it for me, and fixes a minor formatting nit as well.

Jeff Layton committed 18 years ago

Commit e911d0c1 parent d3297a61 file · +10 −10Browse files

Unified · Split

fs/cifs/inode.c+10−10
@@ -219,15 +219,15 @@ int cifs_get_inode_info_unix(struct inode **pinode, · 218 unmodified lines
219219 rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data,
220220 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
221221 CIFS_MOUNT_MAP_SPECIAL_CHR);
222− if (rc) {
223− if (rc == -EREMOTE && !is_dfs_referral) {
224− is_dfs_referral = true;
225− cFYI(DBG2, ("DFS ref"));
226− /* for DFS, server does not give us real inode data */
227− fill_fake_finddataunix(&find_data, sb);
228− rc = 0;
229− }
230− }
222+ if (rc == -EREMOTE && !is_dfs_referral) {
223+ is_dfs_referral = true;
224+ cFYI(DBG2, ("DFS ref"));
225+ /* for DFS, server does not give us real inode data */
226+ fill_fake_finddataunix(&find_data, sb);
227+ rc = 0;
228+ } else if (rc)
229+ goto cgiiu_exit;
230+
231231 num_of_bytes = le64_to_cpu(find_data.NumOfBytes);
232232 end_of_file = le64_to_cpu(find_data.EndOfFile);
233233
@@ -236,7 +236,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, · 2 unmodified lines
236236 *pinode = new_inode(sb);
237237 if (*pinode == NULL) {
238238 rc = -ENOMEM;
239− goto cgiiu_exit;
239+ goto cgiiu_exit;
240240 }
241241 /* Is an i_ino of zero legal? */
242242 /* note ino incremented to unique num in new_inode */