aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-09-18 19:20:27 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:27 -0400
commit2ae78ba85cd7b4c3a164434ab1f6c9e515c6fa1d (patch)
tree0993d53ef7625ee5349f7fcecccd056f930bd6ca /fs/cifs/file.c
parent253641388a49259f6bfefecfb14fa057ca58dc21 (diff)
CIFS: Move reopen code to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c121
1 files changed, 64 insertions, 57 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index dbca2b293e55..628ee17007f8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -459,59 +459,66 @@ out:
459 return rc; 459 return rc;
460} 460}
461 461
462/* Try to reacquire byte range locks that were released when session */ 462/*
463/* to server was lost */ 463 * Try to reacquire byte range locks that were released when session
464 * to server was lost
465 */
464static int cifs_relock_file(struct cifsFileInfo *cifsFile) 466static int cifs_relock_file(struct cifsFileInfo *cifsFile)
465{ 467{
466 int rc = 0; 468 int rc = 0;
467 469
468/* BB list all locks open on this file and relock */ 470 /* BB list all locks open on this file and relock */
469 471
470 return rc; 472 return rc;
471} 473}
472 474
473static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush) 475static int
476cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
474{ 477{
475 int rc = -EACCES; 478 int rc = -EACCES;
476 unsigned int xid; 479 unsigned int xid;
477 __u32 oplock; 480 __u32 oplock;
478 struct cifs_sb_info *cifs_sb; 481 struct cifs_sb_info *cifs_sb;
479 struct cifs_tcon *tcon; 482 struct cifs_tcon *tcon;
480 struct cifsInodeInfo *pCifsInode; 483 struct TCP_Server_Info *server;
484 struct cifsInodeInfo *cinode;
481 struct inode *inode; 485 struct inode *inode;
482 char *full_path = NULL; 486 char *full_path = NULL;
483 int desiredAccess; 487 int desired_access;
484 int disposition = FILE_OPEN; 488 int disposition = FILE_OPEN;
485 int create_options = CREATE_NOT_DIR; 489 int create_options = CREATE_NOT_DIR;
486 __u16 netfid; 490 struct cifs_fid fid;
487 491
488 xid = get_xid(); 492 xid = get_xid();
489 mutex_lock(&pCifsFile->fh_mutex); 493 mutex_lock(&cfile->fh_mutex);
490 if (!pCifsFile->invalidHandle) { 494 if (!cfile->invalidHandle) {
491 mutex_unlock(&pCifsFile->fh_mutex); 495 mutex_unlock(&cfile->fh_mutex);
492 rc = 0; 496 rc = 0;
493 free_xid(xid); 497 free_xid(xid);
494 return rc; 498 return rc;
495 } 499 }
496 500
497 inode = pCifsFile->dentry->d_inode; 501 inode = cfile->dentry->d_inode;
498 cifs_sb = CIFS_SB(inode->i_sb); 502 cifs_sb = CIFS_SB(inode->i_sb);
499 tcon = tlink_tcon(pCifsFile->tlink); 503 tcon = tlink_tcon(cfile->tlink);
504 server = tcon->ses->server;
500 505
501/* can not grab rename sem here because various ops, including 506 /*
502 those that already have the rename sem can end up causing writepage 507 * Can not grab rename sem here because various ops, including those
503 to get called and if the server was down that means we end up here, 508 * that already have the rename sem can end up causing writepage to get
504 and we can never tell if the caller already has the rename_sem */ 509 * called and if the server was down that means we end up here, and we
505 full_path = build_path_from_dentry(pCifsFile->dentry); 510 * can never tell if the caller already has the rename_sem.
511 */
512 full_path = build_path_from_dentry(cfile->dentry);
506 if (full_path == NULL) { 513 if (full_path == NULL) {
507 rc = -ENOMEM; 514 rc = -ENOMEM;
508 mutex_unlock(&pCifsFile->fh_mutex); 515 mutex_unlock(&cfile->fh_mutex);
509 free_xid(xid); 516 free_xid(xid);
510 return rc; 517 return rc;
511 } 518 }
512 519
513 cFYI(1, "inode = 0x%p file flags 0x%x for %s", 520 cFYI(1, "inode = 0x%p file flags 0x%x for %s", inode, cfile->f_flags,
514 inode, pCifsFile->f_flags, full_path); 521 full_path);
515 522
516 if (tcon->ses->server->oplocks) 523 if (tcon->ses->server->oplocks)
517 oplock = REQ_OPLOCK; 524 oplock = REQ_OPLOCK;
@@ -525,69 +532,69 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
525 * O_CREAT, O_EXCL and O_TRUNC already had their effect on the 532 * O_CREAT, O_EXCL and O_TRUNC already had their effect on the
526 * original open. Must mask them off for a reopen. 533 * original open. Must mask them off for a reopen.
527 */ 534 */
528 unsigned int oflags = pCifsFile->f_flags & 535 unsigned int oflags = cfile->f_flags &
529 ~(O_CREAT | O_EXCL | O_TRUNC); 536 ~(O_CREAT | O_EXCL | O_TRUNC);
530 537
531 rc = cifs_posix_open(full_path, NULL, inode->i_sb, 538 rc = cifs_posix_open(full_path, NULL, inode->i_sb,
532 cifs_sb->mnt_file_mode /* ignored */, 539 cifs_sb->mnt_file_mode /* ignored */,
533 oflags, &oplock, &netfid, xid); 540 oflags, &oplock, &fid.netfid, xid);
534 if (rc == 0) { 541 if (rc == 0) {
535 cFYI(1, "posix reopen succeeded"); 542 cFYI(1, "posix reopen succeeded");
536 goto reopen_success; 543 goto reopen_success;
537 } 544 }
538 /* fallthrough to retry open the old way on errors, especially 545 /*
539 in the reconnect path it is important to retry hard */ 546 * fallthrough to retry open the old way on errors, especially
547 * in the reconnect path it is important to retry hard
548 */
540 } 549 }
541 550
542 desiredAccess = cifs_convert_flags(pCifsFile->f_flags); 551 desired_access = cifs_convert_flags(cfile->f_flags);
543 552
544 if (backup_cred(cifs_sb)) 553 if (backup_cred(cifs_sb))
545 create_options |= CREATE_OPEN_BACKUP_INTENT; 554 create_options |= CREATE_OPEN_BACKUP_INTENT;
546 555
547 /* Can not refresh inode by passing in file_info buf to be returned 556 /*
548 by SMBOpen and then calling get_inode_info with returned buf 557 * Can not refresh inode by passing in file_info buf to be returned by
549 since file might have write behind data that needs to be flushed 558 * CIFSSMBOpen and then calling get_inode_info with returned buf since
550 and server version of file size can be stale. If we knew for sure 559 * file might have write behind data that needs to be flushed and server
551 that inode was not dirty locally we could do this */ 560 * version of file size can be stale. If we knew for sure that inode was
552 561 * not dirty locally we could do this.
553 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess, 562 */
554 create_options, &netfid, &oplock, NULL, 563 rc = server->ops->open(xid, tcon, full_path, disposition,
555 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 564 desired_access, create_options, &fid, &oplock,
556 CIFS_MOUNT_MAP_SPECIAL_CHR); 565 NULL, cifs_sb);
557 if (rc) { 566 if (rc) {
558 mutex_unlock(&pCifsFile->fh_mutex); 567 mutex_unlock(&cfile->fh_mutex);
559 cFYI(1, "cifs_open returned 0x%x", rc); 568 cFYI(1, "cifs_reopen returned 0x%x", rc);
560 cFYI(1, "oplock: %d", oplock); 569 cFYI(1, "oplock: %d", oplock);
561 goto reopen_error_exit; 570 goto reopen_error_exit;
562 } 571 }
563 572
564reopen_success: 573reopen_success:
565 pCifsFile->fid.netfid = netfid; 574 cfile->invalidHandle = false;
566 pCifsFile->invalidHandle = false; 575 mutex_unlock(&cfile->fh_mutex);
567 mutex_unlock(&pCifsFile->fh_mutex); 576 cinode = CIFS_I(inode);
568 pCifsInode = CIFS_I(inode);
569 577
570 if (can_flush) { 578 if (can_flush) {
571 rc = filemap_write_and_wait(inode->i_mapping); 579 rc = filemap_write_and_wait(inode->i_mapping);
572 mapping_set_error(inode->i_mapping, rc); 580 mapping_set_error(inode->i_mapping, rc);
573 581
574 if (tcon->unix_ext) 582 if (tcon->unix_ext)
575 rc = cifs_get_inode_info_unix(&inode, 583 rc = cifs_get_inode_info_unix(&inode, full_path,
576 full_path, inode->i_sb, xid); 584 inode->i_sb, xid);
577 else 585 else
578 rc = cifs_get_inode_info(&inode, 586 rc = cifs_get_inode_info(&inode, full_path, NULL,
579 full_path, NULL, inode->i_sb, 587 inode->i_sb, xid, NULL);
580 xid, NULL); 588 }
581 } /* else we are writing out data to server already 589 /*
582 and could deadlock if we tried to flush data, and 590 * Else we are writing out data to server already and could deadlock if
583 since we do not know if we have data that would 591 * we tried to flush data, and since we do not know if we have data that
584 invalidate the current end of file on the server 592 * would invalidate the current end of file on the server we can not go
585 we can not go to the server to get the new inod 593 * to the server to get the new inode info.
586 info */ 594 */
587 595
588 cifs_set_oplock_level(pCifsInode, oplock); 596 server->ops->set_fid(cfile, &fid, oplock);
589 597 cifs_relock_file(cfile);
590 cifs_relock_file(pCifsFile);
591 598
592reopen_error_exit: 599reopen_error_exit:
593 kfree(full_path); 600 kfree(full_path);