diff options
-rw-r--r-- | fs/cifs/cifssmb.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1cd01ba03656..1f3c8a463fcd 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -5074,6 +5074,47 @@ SetAttrLgcyRetry: | |||
5074 | } | 5074 | } |
5075 | #endif /* temporarily unneeded SetAttr legacy function */ | 5075 | #endif /* temporarily unneeded SetAttr legacy function */ |
5076 | 5076 | ||
5077 | static void | ||
5078 | cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, | ||
5079 | const struct cifs_unix_set_info_args *args) | ||
5080 | { | ||
5081 | u64 mode = args->mode; | ||
5082 | |||
5083 | /* | ||
5084 | * Samba server ignores set of file size to zero due to bugs in some | ||
5085 | * older clients, but we should be precise - we use SetFileSize to | ||
5086 | * set file size and do not want to truncate file size to zero | ||
5087 | * accidently as happened on one Samba server beta by putting | ||
5088 | * zero instead of -1 here | ||
5089 | */ | ||
5090 | data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); | ||
5091 | data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); | ||
5092 | data_offset->LastStatusChange = cpu_to_le64(args->ctime); | ||
5093 | data_offset->LastAccessTime = cpu_to_le64(args->atime); | ||
5094 | data_offset->LastModificationTime = cpu_to_le64(args->mtime); | ||
5095 | data_offset->Uid = cpu_to_le64(args->uid); | ||
5096 | data_offset->Gid = cpu_to_le64(args->gid); | ||
5097 | /* better to leave device as zero when it is */ | ||
5098 | data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); | ||
5099 | data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); | ||
5100 | data_offset->Permissions = cpu_to_le64(mode); | ||
5101 | |||
5102 | if (S_ISREG(mode)) | ||
5103 | data_offset->Type = cpu_to_le32(UNIX_FILE); | ||
5104 | else if (S_ISDIR(mode)) | ||
5105 | data_offset->Type = cpu_to_le32(UNIX_DIR); | ||
5106 | else if (S_ISLNK(mode)) | ||
5107 | data_offset->Type = cpu_to_le32(UNIX_SYMLINK); | ||
5108 | else if (S_ISCHR(mode)) | ||
5109 | data_offset->Type = cpu_to_le32(UNIX_CHARDEV); | ||
5110 | else if (S_ISBLK(mode)) | ||
5111 | data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); | ||
5112 | else if (S_ISFIFO(mode)) | ||
5113 | data_offset->Type = cpu_to_le32(UNIX_FIFO); | ||
5114 | else if (S_ISSOCK(mode)) | ||
5115 | data_offset->Type = cpu_to_le32(UNIX_SOCKET); | ||
5116 | } | ||
5117 | |||
5077 | int | 5118 | int |
5078 | CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, | 5119 | CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, |
5079 | const struct cifs_unix_set_info_args *args, | 5120 | const struct cifs_unix_set_info_args *args, |
@@ -5086,7 +5127,6 @@ CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, | |||
5086 | int bytes_returned = 0; | 5127 | int bytes_returned = 0; |
5087 | FILE_UNIX_BASIC_INFO *data_offset; | 5128 | FILE_UNIX_BASIC_INFO *data_offset; |
5088 | __u16 params, param_offset, offset, count, byte_count; | 5129 | __u16 params, param_offset, offset, count, byte_count; |
5089 | __u64 mode = args->mode; | ||
5090 | 5130 | ||
5091 | cFYI(1, ("In SetUID/GID/Mode")); | 5131 | cFYI(1, ("In SetUID/GID/Mode")); |
5092 | setPermsRetry: | 5132 | setPermsRetry: |
@@ -5137,38 +5177,8 @@ setPermsRetry: | |||
5137 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); | 5177 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); |
5138 | pSMB->Reserved4 = 0; | 5178 | pSMB->Reserved4 = 0; |
5139 | pSMB->hdr.smb_buf_length += byte_count; | 5179 | pSMB->hdr.smb_buf_length += byte_count; |
5140 | /* Samba server ignores set of file size to zero due to bugs in some | ||
5141 | older clients, but we should be precise - we use SetFileSize to | ||
5142 | set file size and do not want to truncate file size to zero | ||
5143 | accidently as happened on one Samba server beta by putting | ||
5144 | zero instead of -1 here */ | ||
5145 | data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); | ||
5146 | data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); | ||
5147 | data_offset->LastStatusChange = cpu_to_le64(args->ctime); | ||
5148 | data_offset->LastAccessTime = cpu_to_le64(args->atime); | ||
5149 | data_offset->LastModificationTime = cpu_to_le64(args->mtime); | ||
5150 | data_offset->Uid = cpu_to_le64(args->uid); | ||
5151 | data_offset->Gid = cpu_to_le64(args->gid); | ||
5152 | /* better to leave device as zero when it is */ | ||
5153 | data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); | ||
5154 | data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); | ||
5155 | data_offset->Permissions = cpu_to_le64(mode); | ||
5156 | |||
5157 | if (S_ISREG(mode)) | ||
5158 | data_offset->Type = cpu_to_le32(UNIX_FILE); | ||
5159 | else if (S_ISDIR(mode)) | ||
5160 | data_offset->Type = cpu_to_le32(UNIX_DIR); | ||
5161 | else if (S_ISLNK(mode)) | ||
5162 | data_offset->Type = cpu_to_le32(UNIX_SYMLINK); | ||
5163 | else if (S_ISCHR(mode)) | ||
5164 | data_offset->Type = cpu_to_le32(UNIX_CHARDEV); | ||
5165 | else if (S_ISBLK(mode)) | ||
5166 | data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); | ||
5167 | else if (S_ISFIFO(mode)) | ||
5168 | data_offset->Type = cpu_to_le32(UNIX_FIFO); | ||
5169 | else if (S_ISSOCK(mode)) | ||
5170 | data_offset->Type = cpu_to_le32(UNIX_SOCKET); | ||
5171 | 5180 | ||
5181 | cifs_fill_unix_set_info(data_offset, args); | ||
5172 | 5182 | ||
5173 | pSMB->ByteCount = cpu_to_le16(byte_count); | 5183 | pSMB->ByteCount = cpu_to_le16(byte_count); |
5174 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 5184 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |