diff options
| -rw-r--r-- | fs/cifs/cifsacl.c | 25 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 5 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 5 | ||||
| -rw-r--r-- | fs/cifs/file.c | 4 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 11 | ||||
| -rw-r--r-- | fs/cifs/link.c | 2 |
6 files changed, 30 insertions, 22 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index f93932c21772..1f5a4289b848 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/cifsacl.c | 2 | * fs/cifs/cifsacl.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) International Business Machines Corp., 2007 | 4 | * Copyright (C) International Business Machines Corp., 2007,2008 |
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 6 | * | 6 | * |
| 7 | * Contains the routines for mapping CIFS/NTFS ACLs | 7 | * Contains the routines for mapping CIFS/NTFS ACLs |
| @@ -556,9 +556,9 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
| 556 | 556 | ||
| 557 | /* Retrieve an ACL from the server */ | 557 | /* Retrieve an ACL from the server */ |
| 558 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | 558 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, |
| 559 | const char *path) | 559 | const char *path, const __u16 *pfid) |
| 560 | { | 560 | { |
| 561 | struct cifsFileInfo *open_file; | 561 | struct cifsFileInfo *open_file = NULL; |
| 562 | int unlock_file = FALSE; | 562 | int unlock_file = FALSE; |
| 563 | int xid; | 563 | int xid; |
| 564 | int rc = -EIO; | 564 | int rc = -EIO; |
| @@ -573,7 +573,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
| 573 | return NULL; | 573 | return NULL; |
| 574 | 574 | ||
| 575 | xid = GetXid(); | 575 | xid = GetXid(); |
| 576 | open_file = find_readable_file(CIFS_I(inode)); | 576 | if (pfid == NULL) |
| 577 | open_file = find_readable_file(CIFS_I(inode)); | ||
| 578 | else | ||
| 579 | fid = *pfid; | ||
| 580 | |||
| 577 | sb = inode->i_sb; | 581 | sb = inode->i_sb; |
| 578 | if (sb == NULL) { | 582 | if (sb == NULL) { |
| 579 | FreeXid(xid); | 583 | FreeXid(xid); |
| @@ -584,7 +588,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
| 584 | if (open_file) { | 588 | if (open_file) { |
| 585 | unlock_file = TRUE; | 589 | unlock_file = TRUE; |
| 586 | fid = open_file->netfid; | 590 | fid = open_file->netfid; |
| 587 | } else { | 591 | } else if (pfid == NULL) { |
| 588 | int oplock = FALSE; | 592 | int oplock = FALSE; |
| 589 | /* open file */ | 593 | /* open file */ |
| 590 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | 594 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, |
| @@ -600,10 +604,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
| 600 | 604 | ||
| 601 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | 605 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); |
| 602 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); | 606 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); |
| 603 | if (unlock_file == TRUE) | 607 | if (unlock_file == TRUE) /* find_readable_file increments ref count */ |
| 604 | atomic_dec(&open_file->wrtPending); | 608 | atomic_dec(&open_file->wrtPending); |
| 605 | else | 609 | else if (pfid == NULL) /* if opened above we have to close the handle */ |
| 606 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | 610 | CIFSSMBClose(xid, cifs_sb->tcon, fid); |
| 611 | /* else handle was passed in by caller */ | ||
| 607 | 612 | ||
| 608 | FreeXid(xid); | 613 | FreeXid(xid); |
| 609 | return pntsd; | 614 | return pntsd; |
| @@ -664,14 +669,14 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | |||
| 664 | } | 669 | } |
| 665 | 670 | ||
| 666 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 671 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
| 667 | void acl_to_uid_mode(struct inode *inode, const char *path) | 672 | void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid) |
| 668 | { | 673 | { |
| 669 | struct cifs_ntsd *pntsd = NULL; | 674 | struct cifs_ntsd *pntsd = NULL; |
| 670 | u32 acllen = 0; | 675 | u32 acllen = 0; |
| 671 | int rc = 0; | 676 | int rc = 0; |
| 672 | 677 | ||
| 673 | cFYI(DBG2, ("converting ACL to mode for %s", path)); | 678 | cFYI(DBG2, ("converting ACL to mode for %s", path)); |
| 674 | pntsd = get_cifs_acl(&acllen, inode, path); | 679 | pntsd = get_cifs_acl(&acllen, inode, path, pfid); |
| 675 | 680 | ||
| 676 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | 681 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ |
| 677 | if (pntsd) | 682 | if (pntsd) |
| @@ -694,7 +699,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | |||
| 694 | cFYI(DBG2, ("set ACL from mode for %s", path)); | 699 | cFYI(DBG2, ("set ACL from mode for %s", path)); |
| 695 | 700 | ||
| 696 | /* Get the security descriptor */ | 701 | /* Get the security descriptor */ |
| 697 | pntsd = get_cifs_acl(&acllen, inode, path); | 702 | pntsd = get_cifs_acl(&acllen, inode, path, NULL); |
| 698 | 703 | ||
| 699 | /* Add three ACEs for owner, group, everyone getting rid of | 704 | /* Add three ACEs for owner, group, everyone getting rid of |
| 700 | other ACEs as chmod disables ACEs and set the security descriptor */ | 705 | other ACEs as chmod disables ACEs and set the security descriptor */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index a0414bda587c..7e5e0e78cd72 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -92,11 +92,12 @@ extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); | |||
| 92 | extern int cifs_get_inode_info(struct inode **pinode, | 92 | extern int cifs_get_inode_info(struct inode **pinode, |
| 93 | const unsigned char *search_path, | 93 | const unsigned char *search_path, |
| 94 | FILE_ALL_INFO * pfile_info, | 94 | FILE_ALL_INFO * pfile_info, |
| 95 | struct super_block *sb, int xid); | 95 | struct super_block *sb, int xid, const __u16 *pfid); |
| 96 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 96 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
| 97 | const unsigned char *search_path, | 97 | const unsigned char *search_path, |
| 98 | struct super_block *sb, int xid); | 98 | struct super_block *sb, int xid); |
| 99 | extern void acl_to_uid_mode(struct inode *inode, const char *search_path); | 99 | extern void acl_to_uid_mode(struct inode *inode, const char *path, |
| 100 | const __u16 *pfid); | ||
| 100 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); | 101 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); |
| 101 | 102 | ||
| 102 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 103 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 4e83b47c4b34..0f5c62ba4038 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -229,7 +229,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 229 | inode->i_sb, xid); | 229 | inode->i_sb, xid); |
| 230 | else { | 230 | else { |
| 231 | rc = cifs_get_inode_info(&newinode, full_path, | 231 | rc = cifs_get_inode_info(&newinode, full_path, |
| 232 | buf, inode->i_sb, xid); | 232 | buf, inode->i_sb, xid, |
| 233 | &fileHandle); | ||
| 233 | if (newinode) { | 234 | if (newinode) { |
| 234 | newinode->i_mode = mode; | 235 | newinode->i_mode = mode; |
| 235 | if ((oplock & CIFS_CREATE_ACTION) && | 236 | if ((oplock & CIFS_CREATE_ACTION) && |
| @@ -483,7 +484,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
| 483 | parent_dir_inode->i_sb, xid); | 484 | parent_dir_inode->i_sb, xid); |
| 484 | else | 485 | else |
| 485 | rc = cifs_get_inode_info(&newInode, full_path, NULL, | 486 | rc = cifs_get_inode_info(&newInode, full_path, NULL, |
| 486 | parent_dir_inode->i_sb, xid); | 487 | parent_dir_inode->i_sb, xid, NULL); |
| 487 | 488 | ||
| 488 | if ((rc == 0) && (newInode != NULL)) { | 489 | if ((rc == 0) && (newInode != NULL)) { |
| 489 | if (pTcon->nocase) | 490 | if (pTcon->nocase) |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index fa849c91d323..40b690073fc1 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -145,7 +145,7 @@ client_can_cache: | |||
| 145 | full_path, inode->i_sb, xid); | 145 | full_path, inode->i_sb, xid); |
| 146 | else | 146 | else |
| 147 | rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, | 147 | rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, |
| 148 | full_path, buf, inode->i_sb, xid); | 148 | full_path, buf, inode->i_sb, xid, NULL); |
| 149 | 149 | ||
| 150 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 150 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
| 151 | pCifsInode->clientCanCacheAll = TRUE; | 151 | pCifsInode->clientCanCacheAll = TRUE; |
| @@ -440,7 +440,7 @@ reopen_error_exit: | |||
| 440 | else | 440 | else |
| 441 | rc = cifs_get_inode_info(&inode, | 441 | rc = cifs_get_inode_info(&inode, |
| 442 | full_path, NULL, inode->i_sb, | 442 | full_path, NULL, inode->i_sb, |
| 443 | xid); | 443 | xid, NULL); |
| 444 | } /* else we are writing out data to server already | 444 | } /* else we are writing out data to server already |
| 445 | and could deadlock if we tried to flush data, and | 445 | and could deadlock if we tried to flush data, and |
| 446 | since we do not know if we have data that would | 446 | since we do not know if we have data that would |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index e57e5c46ad48..7e4c24491729 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -371,7 +371,7 @@ static int get_sfu_mode(struct inode *inode, | |||
| 371 | 371 | ||
| 372 | int cifs_get_inode_info(struct inode **pinode, | 372 | int cifs_get_inode_info(struct inode **pinode, |
| 373 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, | 373 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, |
| 374 | struct super_block *sb, int xid) | 374 | struct super_block *sb, int xid, const __u16 *pfid) |
| 375 | { | 375 | { |
| 376 | int rc = 0; | 376 | int rc = 0; |
| 377 | struct cifsTconInfo *pTcon; | 377 | struct cifsTconInfo *pTcon; |
| @@ -569,7 +569,7 @@ try_again_CIFSSMBQPathInfo: | |||
| 569 | /* fill in 0777 bits from ACL */ | 569 | /* fill in 0777 bits from ACL */ |
| 570 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 570 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
| 571 | cFYI(1, ("Getting mode bits from ACL")); | 571 | cFYI(1, ("Getting mode bits from ACL")); |
| 572 | acl_to_uid_mode(inode, search_path); | 572 | acl_to_uid_mode(inode, search_path, pfid); |
| 573 | } | 573 | } |
| 574 | #endif | 574 | #endif |
| 575 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 575 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
| @@ -616,7 +616,8 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
| 616 | if (cifs_sb->tcon->unix_ext) | 616 | if (cifs_sb->tcon->unix_ext) |
| 617 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); | 617 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); |
| 618 | else | 618 | else |
| 619 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); | 619 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid, |
| 620 | NULL); | ||
| 620 | if (rc && cifs_sb->tcon->ipc) { | 621 | if (rc && cifs_sb->tcon->ipc) { |
| 621 | cFYI(1, ("ipc connection - fake read inode")); | 622 | cFYI(1, ("ipc connection - fake read inode")); |
| 622 | inode->i_mode |= S_IFDIR; | 623 | inode->i_mode |= S_IFDIR; |
| @@ -949,7 +950,7 @@ mkdir_get_info: | |||
| 949 | inode->i_sb, xid); | 950 | inode->i_sb, xid); |
| 950 | else | 951 | else |
| 951 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | 952 | rc = cifs_get_inode_info(&newinode, full_path, NULL, |
| 952 | inode->i_sb, xid); | 953 | inode->i_sb, xid, NULL); |
| 953 | 954 | ||
| 954 | if (pTcon->nocase) | 955 | if (pTcon->nocase) |
| 955 | direntry->d_op = &cifs_ci_dentry_ops; | 956 | direntry->d_op = &cifs_ci_dentry_ops; |
| @@ -1231,7 +1232,7 @@ int cifs_revalidate(struct dentry *direntry) | |||
| 1231 | } | 1232 | } |
| 1232 | } else { | 1233 | } else { |
| 1233 | rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, | 1234 | rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, |
| 1234 | direntry->d_sb, xid); | 1235 | direntry->d_sb, xid, NULL); |
| 1235 | if (rc) { | 1236 | if (rc) { |
| 1236 | cFYI(1, ("error on getting revalidate info %d", rc)); | 1237 | cFYI(1, ("error on getting revalidate info %d", rc)); |
| 1237 | /* if (rc != -ENOENT) | 1238 | /* if (rc != -ENOENT) |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 1d6fb01b8e6d..d4e7ec93285f 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -205,7 +205,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
| 205 | inode->i_sb, xid); | 205 | inode->i_sb, xid); |
| 206 | else | 206 | else |
| 207 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | 207 | rc = cifs_get_inode_info(&newinode, full_path, NULL, |
| 208 | inode->i_sb, xid); | 208 | inode->i_sb, xid, NULL); |
| 209 | 209 | ||
| 210 | if (rc != 0) { | 210 | if (rc != 0) { |
| 211 | cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d", | 211 | cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d", |
