diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b4a18c1cab0a..e9c1573f6aa7 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -110,7 +110,6 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
110 | &pCifsInode->openFileList); | 110 | &pCifsInode->openFileList); |
111 | } | 111 | } |
112 | write_unlock(&GlobalSMBSeslock); | 112 | write_unlock(&GlobalSMBSeslock); |
113 | write_unlock(&file->f_owner.lock); | ||
114 | if (pCifsInode->clientCanCacheRead) { | 113 | if (pCifsInode->clientCanCacheRead) { |
115 | /* we have the inode open somewhere else | 114 | /* we have the inode open somewhere else |
116 | no need to discard cache data */ | 115 | no need to discard cache data */ |
@@ -201,7 +200,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
201 | } else { | 200 | } else { |
202 | if (file->f_flags & O_EXCL) | 201 | if (file->f_flags & O_EXCL) |
203 | cERROR(1, ("could not find file instance for " | 202 | cERROR(1, ("could not find file instance for " |
204 | "new file %p ", file)); | 203 | "new file %p", file)); |
205 | } | 204 | } |
206 | } | 205 | } |
207 | 206 | ||
@@ -260,10 +259,15 @@ int cifs_open(struct inode *inode, struct file *file) | |||
260 | rc = -ENOMEM; | 259 | rc = -ENOMEM; |
261 | goto out; | 260 | goto out; |
262 | } | 261 | } |
263 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, | 262 | |
264 | CREATE_NOT_DIR, &netfid, &oplock, buf, | 263 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) |
264 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | ||
265 | desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, | ||
265 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags | 266 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags |
266 | & CIFS_MOUNT_MAP_SPECIAL_CHR); | 267 | & CIFS_MOUNT_MAP_SPECIAL_CHR); |
268 | else | ||
269 | rc = -EIO; /* no NT SMB support fall into legacy open below */ | ||
270 | |||
267 | if (rc == -EIO) { | 271 | if (rc == -EIO) { |
268 | /* Old server, try legacy style OpenX */ | 272 | /* Old server, try legacy style OpenX */ |
269 | rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, | 273 | rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, |
@@ -272,7 +276,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
272 | & CIFS_MOUNT_MAP_SPECIAL_CHR); | 276 | & CIFS_MOUNT_MAP_SPECIAL_CHR); |
273 | } | 277 | } |
274 | if (rc) { | 278 | if (rc) { |
275 | cFYI(1, ("cifs_open returned 0x%x ", rc)); | 279 | cFYI(1, ("cifs_open returned 0x%x", rc)); |
276 | goto out; | 280 | goto out; |
277 | } | 281 | } |
278 | file->private_data = | 282 | file->private_data = |
@@ -282,7 +286,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
282 | goto out; | 286 | goto out; |
283 | } | 287 | } |
284 | pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); | 288 | pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); |
285 | write_lock(&file->f_owner.lock); | ||
286 | write_lock(&GlobalSMBSeslock); | 289 | write_lock(&GlobalSMBSeslock); |
287 | list_add(&pCifsFile->tlist, &pTcon->openFileList); | 290 | list_add(&pCifsFile->tlist, &pTcon->openFileList); |
288 | 291 | ||
@@ -293,7 +296,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
293 | &oplock, buf, full_path, xid); | 296 | &oplock, buf, full_path, xid); |
294 | } else { | 297 | } else { |
295 | write_unlock(&GlobalSMBSeslock); | 298 | write_unlock(&GlobalSMBSeslock); |
296 | write_unlock(&file->f_owner.lock); | ||
297 | } | 299 | } |
298 | 300 | ||
299 | if (oplock & CIFS_CREATE_ACTION) { | 301 | if (oplock & CIFS_CREATE_ACTION) { |
@@ -409,8 +411,8 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
409 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 411 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
410 | if (rc) { | 412 | if (rc) { |
411 | up(&pCifsFile->fh_sem); | 413 | up(&pCifsFile->fh_sem); |
412 | cFYI(1, ("cifs_open returned 0x%x ", rc)); | 414 | cFYI(1, ("cifs_open returned 0x%x", rc)); |
413 | cFYI(1, ("oplock: %d ", oplock)); | 415 | cFYI(1, ("oplock: %d", oplock)); |
414 | } else { | 416 | } else { |
415 | pCifsFile->netfid = netfid; | 417 | pCifsFile->netfid = netfid; |
416 | pCifsFile->invalidHandle = FALSE; | 418 | pCifsFile->invalidHandle = FALSE; |
@@ -472,7 +474,6 @@ int cifs_close(struct inode *inode, struct file *file) | |||
472 | pTcon = cifs_sb->tcon; | 474 | pTcon = cifs_sb->tcon; |
473 | if (pSMBFile) { | 475 | if (pSMBFile) { |
474 | pSMBFile->closePend = TRUE; | 476 | pSMBFile->closePend = TRUE; |
475 | write_lock(&file->f_owner.lock); | ||
476 | if (pTcon) { | 477 | if (pTcon) { |
477 | /* no sense reconnecting to close a file that is | 478 | /* no sense reconnecting to close a file that is |
478 | already closed */ | 479 | already closed */ |
@@ -487,23 +488,18 @@ int cifs_close(struct inode *inode, struct file *file) | |||
487 | the struct would be in each open file, | 488 | the struct would be in each open file, |
488 | but this should give enough time to | 489 | but this should give enough time to |
489 | clear the socket */ | 490 | clear the socket */ |
490 | write_unlock(&file->f_owner.lock); | ||
491 | cERROR(1,("close with pending writes")); | 491 | cERROR(1,("close with pending writes")); |
492 | msleep(timeout); | 492 | msleep(timeout); |
493 | write_lock(&file->f_owner.lock); | ||
494 | timeout *= 4; | 493 | timeout *= 4; |
495 | } | 494 | } |
496 | write_unlock(&file->f_owner.lock); | ||
497 | rc = CIFSSMBClose(xid, pTcon, | 495 | rc = CIFSSMBClose(xid, pTcon, |
498 | pSMBFile->netfid); | 496 | pSMBFile->netfid); |
499 | write_lock(&file->f_owner.lock); | ||
500 | } | 497 | } |
501 | } | 498 | } |
502 | write_lock(&GlobalSMBSeslock); | 499 | write_lock(&GlobalSMBSeslock); |
503 | list_del(&pSMBFile->flist); | 500 | list_del(&pSMBFile->flist); |
504 | list_del(&pSMBFile->tlist); | 501 | list_del(&pSMBFile->tlist); |
505 | write_unlock(&GlobalSMBSeslock); | 502 | write_unlock(&GlobalSMBSeslock); |
506 | write_unlock(&file->f_owner.lock); | ||
507 | kfree(pSMBFile->search_resume_name); | 503 | kfree(pSMBFile->search_resume_name); |
508 | kfree(file->private_data); | 504 | kfree(file->private_data); |
509 | file->private_data = NULL; | 505 | file->private_data = NULL; |
@@ -531,7 +527,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
531 | (struct cifsFileInfo *)file->private_data; | 527 | (struct cifsFileInfo *)file->private_data; |
532 | char *ptmp; | 528 | char *ptmp; |
533 | 529 | ||
534 | cFYI(1, ("Closedir inode = 0x%p with ", inode)); | 530 | cFYI(1, ("Closedir inode = 0x%p", inode)); |
535 | 531 | ||
536 | xid = GetXid(); | 532 | xid = GetXid(); |
537 | 533 | ||
@@ -605,7 +601,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
605 | } | 601 | } |
606 | if (pfLock->fl_flags & FL_ACCESS) | 602 | if (pfLock->fl_flags & FL_ACCESS) |
607 | cFYI(1, ("Process suspended by mandatory locking - " | 603 | cFYI(1, ("Process suspended by mandatory locking - " |
608 | "not implemented yet ")); | 604 | "not implemented yet")); |
609 | if (pfLock->fl_flags & FL_LEASE) | 605 | if (pfLock->fl_flags & FL_LEASE) |
610 | cFYI(1, ("Lease on file - not implemented yet")); | 606 | cFYI(1, ("Lease on file - not implemented yet")); |
611 | if (pfLock->fl_flags & | 607 | if (pfLock->fl_flags & |
@@ -1375,7 +1371,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1375 | 1371 | ||
1376 | xid = GetXid(); | 1372 | xid = GetXid(); |
1377 | 1373 | ||
1378 | cFYI(1, ("Sync file - name: %s datasync: 0x%x ", | 1374 | cFYI(1, ("Sync file - name: %s datasync: 0x%x", |
1379 | dentry->d_name.name, datasync)); | 1375 | dentry->d_name.name, datasync)); |
1380 | 1376 | ||
1381 | rc = filemap_fdatawrite(inode->i_mapping); | 1377 | rc = filemap_fdatawrite(inode->i_mapping); |
@@ -1404,7 +1400,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1404 | /* fill in rpages then | 1400 | /* fill in rpages then |
1405 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ | 1401 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ |
1406 | 1402 | ||
1407 | /* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index)); | 1403 | /* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); |
1408 | 1404 | ||
1409 | #if 0 | 1405 | #if 0 |
1410 | if (rc < 0) | 1406 | if (rc < 0) |
@@ -1836,7 +1832,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
1836 | if (rc < 0) | 1832 | if (rc < 0) |
1837 | goto io_error; | 1833 | goto io_error; |
1838 | else | 1834 | else |
1839 | cFYI(1, ("Bytes read %d ",rc)); | 1835 | cFYI(1, ("Bytes read %d",rc)); |
1840 | 1836 | ||
1841 | file->f_dentry->d_inode->i_atime = | 1837 | file->f_dentry->d_inode->i_atime = |
1842 | current_fs_time(file->f_dentry->d_inode->i_sb); | 1838 | current_fs_time(file->f_dentry->d_inode->i_sb); |
@@ -1957,3 +1953,19 @@ struct address_space_operations cifs_addr_ops = { | |||
1957 | /* .sync_page = cifs_sync_page, */ | 1953 | /* .sync_page = cifs_sync_page, */ |
1958 | /* .direct_IO = */ | 1954 | /* .direct_IO = */ |
1959 | }; | 1955 | }; |
1956 | |||
1957 | /* | ||
1958 | * cifs_readpages requires the server to support a buffer large enough to | ||
1959 | * contain the header plus one complete page of data. Otherwise, we need | ||
1960 | * to leave cifs_readpages out of the address space operations. | ||
1961 | */ | ||
1962 | struct address_space_operations cifs_addr_ops_smallbuf = { | ||
1963 | .readpage = cifs_readpage, | ||
1964 | .writepage = cifs_writepage, | ||
1965 | .writepages = cifs_writepages, | ||
1966 | .prepare_write = cifs_prepare_write, | ||
1967 | .commit_write = cifs_commit_write, | ||
1968 | .set_page_dirty = __set_page_dirty_nobuffers, | ||
1969 | /* .sync_page = cifs_sync_page, */ | ||
1970 | /* .direct_IO = */ | ||
1971 | }; | ||