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, |
