diff options
author | Jeff Layton <jlayton@redhat.com> | 2010-09-29 19:51:11 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-10-06 12:12:49 -0400 |
commit | 13cfb7334eb6fd0fc06da5589aea1e947791f1d6 (patch) | |
tree | 56d884f6a5dbcf8b259247fdad55c9158bd4d865 /fs/cifs/file.c | |
parent | 7ffec372458d163492e56e663a1b3a2d7be0a0a2 (diff) |
cifs: have cifsFileInfo hold a reference to a tlink rather than tcon pointer
cifsFileInfo needs a pointer to a tcon, but it doesn't currently hold a
reference to it. Change it to keep a pointer to a tcon_link instead and
hold a reference to it.
That will keep the tcon from being freed until the file is closed.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1e375abc5eb3..24332d437150 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -283,7 +283,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
283 | 283 | ||
284 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, | 284 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, |
285 | file->f_path.mnt, | 285 | file->f_path.mnt, |
286 | tcon, oflags, oplock); | 286 | tlink, oflags, oplock); |
287 | if (pCifsFile == NULL) { | 287 | if (pCifsFile == NULL) { |
288 | CIFSSMBClose(xid, tcon, netfid); | 288 | CIFSSMBClose(xid, tcon, netfid); |
289 | rc = -ENOMEM; | 289 | rc = -ENOMEM; |
@@ -376,7 +376,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
376 | goto out; | 376 | goto out; |
377 | 377 | ||
378 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, | 378 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, |
379 | tcon, file->f_flags, oplock); | 379 | tlink, file->f_flags, oplock); |
380 | if (pCifsFile == NULL) { | 380 | if (pCifsFile == NULL) { |
381 | rc = -ENOMEM; | 381 | rc = -ENOMEM; |
382 | goto out; | 382 | goto out; |
@@ -468,7 +468,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush) | |||
468 | } | 468 | } |
469 | 469 | ||
470 | cifs_sb = CIFS_SB(inode->i_sb); | 470 | cifs_sb = CIFS_SB(inode->i_sb); |
471 | tcon = pCifsFile->tcon; | 471 | tcon = tlink_tcon(pCifsFile->tlink); |
472 | 472 | ||
473 | /* can not grab rename sem here because various ops, including | 473 | /* can not grab rename sem here because various ops, including |
474 | those that already have the rename sem can end up causing writepage | 474 | those that already have the rename sem can end up causing writepage |
@@ -582,7 +582,7 @@ int cifs_close(struct inode *inode, struct file *file) | |||
582 | xid = GetXid(); | 582 | xid = GetXid(); |
583 | 583 | ||
584 | cifs_sb = CIFS_SB(inode->i_sb); | 584 | cifs_sb = CIFS_SB(inode->i_sb); |
585 | pTcon = pSMBFile->tcon; | 585 | pTcon = tlink_tcon(pSMBFile->tlink); |
586 | if (pSMBFile) { | 586 | if (pSMBFile) { |
587 | struct cifsLockInfo *li, *tmp; | 587 | struct cifsLockInfo *li, *tmp; |
588 | write_lock(&GlobalSMBSeslock); | 588 | write_lock(&GlobalSMBSeslock); |
@@ -660,7 +660,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
660 | xid = GetXid(); | 660 | xid = GetXid(); |
661 | 661 | ||
662 | if (pCFileStruct) { | 662 | if (pCFileStruct) { |
663 | struct cifsTconInfo *pTcon = pCFileStruct->tcon; | 663 | struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink); |
664 | 664 | ||
665 | cFYI(1, "Freeing private data in close dir"); | 665 | cFYI(1, "Freeing private data in close dir"); |
666 | write_lock(&GlobalSMBSeslock); | 666 | write_lock(&GlobalSMBSeslock); |
@@ -684,6 +684,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
684 | else | 684 | else |
685 | cifs_buf_release(ptmp); | 685 | cifs_buf_release(ptmp); |
686 | } | 686 | } |
687 | cifs_put_tlink(pCFileStruct->tlink); | ||
687 | kfree(file->private_data); | 688 | kfree(file->private_data); |
688 | file->private_data = NULL; | 689 | file->private_data = NULL; |
689 | } | 690 | } |
@@ -770,7 +771,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
770 | cFYI(1, "Unknown type of lock"); | 771 | cFYI(1, "Unknown type of lock"); |
771 | 772 | ||
772 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 773 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
773 | tcon = ((struct cifsFileInfo *)file->private_data)->tcon; | 774 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); |
774 | 775 | ||
775 | if (file->private_data == NULL) { | 776 | if (file->private_data == NULL) { |
776 | rc = -EBADF; | 777 | rc = -EBADF; |
@@ -970,7 +971,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
970 | return -EBADF; | 971 | return -EBADF; |
971 | 972 | ||
972 | open_file = file->private_data; | 973 | open_file = file->private_data; |
973 | pTcon = open_file->tcon; | 974 | pTcon = tlink_tcon(open_file->tlink); |
974 | 975 | ||
975 | rc = generic_write_checks(file, poffset, &write_size, 0); | 976 | rc = generic_write_checks(file, poffset, &write_size, 0); |
976 | if (rc) | 977 | if (rc) |
@@ -1071,7 +1072,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
1071 | if (file->private_data == NULL) | 1072 | if (file->private_data == NULL) |
1072 | return -EBADF; | 1073 | return -EBADF; |
1073 | open_file = file->private_data; | 1074 | open_file = file->private_data; |
1074 | pTcon = open_file->tcon; | 1075 | pTcon = tlink_tcon(open_file->tlink); |
1075 | 1076 | ||
1076 | xid = GetXid(); | 1077 | xid = GetXid(); |
1077 | 1078 | ||
@@ -1393,7 +1394,7 @@ static int cifs_writepages(struct address_space *mapping, | |||
1393 | return generic_writepages(mapping, wbc); | 1394 | return generic_writepages(mapping, wbc); |
1394 | } | 1395 | } |
1395 | 1396 | ||
1396 | tcon = open_file->tcon; | 1397 | tcon = tlink_tcon(open_file->tlink); |
1397 | if (!experimEnabled && tcon->ses->server->secMode & | 1398 | if (!experimEnabled && tcon->ses->server->secMode & |
1398 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { | 1399 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { |
1399 | cifsFileInfo_put(open_file); | 1400 | cifsFileInfo_put(open_file); |
@@ -1672,7 +1673,7 @@ int cifs_fsync(struct file *file, int datasync) | |||
1672 | if (rc == 0) { | 1673 | if (rc == 0) { |
1673 | rc = CIFS_I(inode)->write_behind_rc; | 1674 | rc = CIFS_I(inode)->write_behind_rc; |
1674 | CIFS_I(inode)->write_behind_rc = 0; | 1675 | CIFS_I(inode)->write_behind_rc = 0; |
1675 | tcon = smbfile->tcon; | 1676 | tcon = tlink_tcon(smbfile->tlink); |
1676 | if (!rc && tcon && smbfile && | 1677 | if (!rc && tcon && smbfile && |
1677 | !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) | 1678 | !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) |
1678 | rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); | 1679 | rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); |
@@ -1764,7 +1765,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1764 | return rc; | 1765 | return rc; |
1765 | } | 1766 | } |
1766 | open_file = file->private_data; | 1767 | open_file = file->private_data; |
1767 | pTcon = open_file->tcon; | 1768 | pTcon = tlink_tcon(open_file->tlink); |
1768 | 1769 | ||
1769 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1770 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1770 | cFYI(1, "attempting read on write only file instance"); | 1771 | cFYI(1, "attempting read on write only file instance"); |
@@ -1845,7 +1846,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1845 | return rc; | 1846 | return rc; |
1846 | } | 1847 | } |
1847 | open_file = file->private_data; | 1848 | open_file = file->private_data; |
1848 | pTcon = open_file->tcon; | 1849 | pTcon = tlink_tcon(open_file->tlink); |
1849 | 1850 | ||
1850 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1851 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1851 | cFYI(1, "attempting read on write only file instance"); | 1852 | cFYI(1, "attempting read on write only file instance"); |
@@ -1981,7 +1982,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1981 | } | 1982 | } |
1982 | open_file = file->private_data; | 1983 | open_file = file->private_data; |
1983 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 1984 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
1984 | pTcon = open_file->tcon; | 1985 | pTcon = tlink_tcon(open_file->tlink); |
1985 | 1986 | ||
1986 | /* | 1987 | /* |
1987 | * Reads as many pages as possible from fscache. Returns -ENOBUFS | 1988 | * Reads as many pages as possible from fscache. Returns -ENOBUFS |
@@ -2345,8 +2346,8 @@ void cifs_oplock_break(struct work_struct *work) | |||
2345 | * disconnected since oplock already released by the server | 2346 | * disconnected since oplock already released by the server |
2346 | */ | 2347 | */ |
2347 | if (!cfile->closePend && !cfile->oplock_break_cancelled) { | 2348 | if (!cfile->closePend && !cfile->oplock_break_cancelled) { |
2348 | rc = CIFSSMBLock(0, cfile->tcon, cfile->netfid, 0, 0, 0, 0, | 2349 | rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0, |
2349 | LOCKING_ANDX_OPLOCK_RELEASE, false); | 2350 | 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false); |
2350 | cFYI(1, "Oplock release rc = %d", rc); | 2351 | cFYI(1, "Oplock release rc = %d", rc); |
2351 | } | 2352 | } |
2352 | 2353 | ||