OSDN Git Service

ksmbd: contain default data stream even if xattr is empty
authorNamjae Jeon <linkinjeon@kernel.org>
Sun, 21 Nov 2021 02:32:39 +0000 (11:32 +0900)
committerSteve French <stfrench@microsoft.com>
Thu, 25 Nov 2021 06:09:26 +0000 (00:09 -0600)
If xattr is not supported like exfat or fat, ksmbd server doesn't
contain default data stream in FILE_STREAM_INFORMATION response. It will
cause ppt or doc file update issue if local filesystem is such as ones.
This patch move goto statement to contain it.

Fixes: 9f6323311c70 ("ksmbd: add default data stream name in FILE_STREAM_INFORMATION")
Cc: stable@vger.kernel.org # v5.15
Acked-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/ksmbd/smb2pdu.c

index a513ea5..370a32b 100644 (file)
@@ -4459,6 +4459,12 @@ static void get_file_stream_info(struct ksmbd_work *work,
                         &stat);
        file_info = (struct smb2_file_stream_info *)rsp->Buffer;
 
+       buf_free_len =
+               smb2_calc_max_out_buf_len(work, 8,
+                                         le32_to_cpu(req->OutputBufferLength));
+       if (buf_free_len < 0)
+               goto out;
+
        xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
        if (xattr_list_len < 0) {
                goto out;
@@ -4467,12 +4473,6 @@ static void get_file_stream_info(struct ksmbd_work *work,
                goto out;
        }
 
-       buf_free_len =
-               smb2_calc_max_out_buf_len(work, 8,
-                                         le32_to_cpu(req->OutputBufferLength));
-       if (buf_free_len < 0)
-               goto out;
-
        while (idx < xattr_list_len) {
                stream_name = xattr_list + idx;
                streamlen = strlen(stream_name);
@@ -4516,6 +4516,7 @@ static void get_file_stream_info(struct ksmbd_work *work,
                file_info->NextEntryOffset = cpu_to_le32(next);
        }
 
+out:
        if (!S_ISDIR(stat.mode) &&
            buf_free_len >= sizeof(struct smb2_file_stream_info) + 7 * 2) {
                file_info = (struct smb2_file_stream_info *)
@@ -4524,14 +4525,13 @@ static void get_file_stream_info(struct ksmbd_work *work,
                                              "::$DATA", 7, conn->local_nls, 0);
                streamlen *= 2;
                file_info->StreamNameLength = cpu_to_le32(streamlen);
-               file_info->StreamSize = 0;
-               file_info->StreamAllocationSize = 0;
+               file_info->StreamSize = cpu_to_le64(stat.size);
+               file_info->StreamAllocationSize = cpu_to_le64(stat.blocks << 9);
                nbytes += sizeof(struct smb2_file_stream_info) + streamlen;
        }
 
        /* last entry offset should be 0 */
        file_info->NextEntryOffset = 0;
-out:
        kvfree(xattr_list);
 
        rsp->OutputBufferLength = cpu_to_le32(nbytes);