aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-05-22 09:31:40 -0400
committerSteve French <sfrench@us.ibm.com>2008-05-23 14:17:09 -0400
commit4468eb3fd102cad559e51594a01cbc65b994d264 (patch)
tree247fe6ab216b047e3f48aee07e845b17d2447ed7 /fs/cifs/inode.c
parentaaa9bbe039febf1d3a0f3a374deea0680d9f5758 (diff)
on non-posix shares, clear write bits in mode when ATTR_READONLY is set
When mounting a share with posix extensions disabled, cifs_get_inode_info turns off all the write bits in the mode for regular files if ATTR_READONLY is set. Directories and other inode types, however, can also have ATTR_READONLY set, but the mode gives no indication of this. This patch makes this apply to other inode types besides regular files. It also cleans up how modes are set in cifs_get_inode_info for both the "normal" and "dynperm" cases. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c76
1 files changed, 36 insertions, 40 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 129dbfe4dca7..ae5bcaf2031c 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -418,6 +418,7 @@ int cifs_get_inode_info(struct inode **pinode,
418 char *buf = NULL; 418 char *buf = NULL;
419 bool adjustTZ = false; 419 bool adjustTZ = false;
420 bool is_dfs_referral = false; 420 bool is_dfs_referral = false;
421 umode_t default_mode;
421 422
422 pTcon = cifs_sb->tcon; 423 pTcon = cifs_sb->tcon;
423 cFYI(1, ("Getting info on %s", full_path)); 424 cFYI(1, ("Getting info on %s", full_path));
@@ -530,47 +531,42 @@ int cifs_get_inode_info(struct inode **pinode,
530 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; 531 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
531 } 532 }
532 533
533 /* set default mode. will override for dirs below */ 534 /* get default inode mode */
534 if (atomic_read(&cifsInfo->inUse) == 0) 535 if (attr & ATTR_DIRECTORY)
535 /* new inode, can safely set these fields */ 536 default_mode = cifs_sb->mnt_dir_mode;
536 inode->i_mode = cifs_sb->mnt_file_mode; 537 else
537 else /* since we set the inode type below we need to mask off 538 default_mode = cifs_sb->mnt_file_mode;
538 to avoid strange results if type changes and both 539
539 get orred in */ 540 /* set permission bits */
540 inode->i_mode &= ~S_IFMT; 541 if (atomic_read(&cifsInfo->inUse) == 0 ||
541/* if (attr & ATTR_REPARSE) */ 542 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
542 /* We no longer handle these as symlinks because we could not 543 inode->i_mode = default_mode;
543 follow them due to the absolute path with drive letter */ 544 else {
544 if (attr & ATTR_DIRECTORY) { 545 /* just reenable write bits if !ATTR_READONLY */
545 /* override default perms since we do not do byte range locking 546 if ((inode->i_mode & S_IWUGO) == 0 &&
546 on dirs */ 547 (attr & ATTR_READONLY) == 0)
547 inode->i_mode = cifs_sb->mnt_dir_mode; 548 inode->i_mode |= (S_IWUGO & default_mode);
548 inode->i_mode |= S_IFDIR; 549 inode->i_mode &= ~S_IFMT;
549 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 550 }
550 (cifsInfo->cifsAttrs & ATTR_SYSTEM) && 551 /* clear write bits if ATTR_READONLY is set */
551 /* No need to le64 convert size of zero */ 552 if (attr & ATTR_READONLY)
552 (pfindData->EndOfFile == 0)) { 553 inode->i_mode &= ~S_IWUGO;
553 inode->i_mode = cifs_sb->mnt_file_mode; 554
554 inode->i_mode |= S_IFIFO; 555 /* set inode type */
555/* BB Finish for SFU style symlinks and devices */ 556 if ((attr & ATTR_SYSTEM) &&
556 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 557 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
557 (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { 558 /* no need to fix endianness on 0 */
558 if (decode_sfu_inode(inode, le64_to_cpu(pfindData->EndOfFile), 559 if (pfindData->EndOfFile == 0)
559 full_path, cifs_sb, xid)) 560 inode->i_mode |= S_IFIFO;
560 cFYI(1, ("Unrecognized sfu inode type")); 561 else if (decode_sfu_inode(inode,
561 562 le64_to_cpu(pfindData->EndOfFile),
562 cFYI(1, ("sfu mode 0%o", inode->i_mode)); 563 full_path, cifs_sb, xid))
564 cFYI(1, ("unknown SFU file type\n"));
563 } else { 565 } else {
564 inode->i_mode |= S_IFREG; 566 if (attr & ATTR_DIRECTORY)
565 /* treat dos attribute of read-only as read-only mode eg 555 */ 567 inode->i_mode |= S_IFDIR;
566 if (cifsInfo->cifsAttrs & ATTR_READONLY) 568 else
567 inode->i_mode &= ~(S_IWUGO); 569 inode->i_mode |= S_IFREG;
568 else if ((inode->i_mode & S_IWUGO) == 0)
569 /* the ATTR_READONLY flag may have been */
570 /* changed on server -- set any w bits */
571 /* allowed by mnt_file_mode */
572 inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
573 /* BB add code to validate if device or weird share or device type? */
574 } 570 }
575 571
576 spin_lock(&inode->i_lock); 572 spin_lock(&inode->i_lock);