Samba共享传输大文件(ex:1G)失败的问题
1:问题描述
1.1 基本信息
遇见这样一个bug,路由器有USB share的功能,可将U盘内的文件通过samba和LAN端PC机中文件进行共享,测试发现小文件可正常共享,一旦文件大了(比如1G左右),window端便显示一直在计算文件大小,最后客户端(LAN pc)会因为服务器许久不回一个Subcommand:SET_FILE_INFO(0x0008)的报文而出现timeout,导致文件传输失败.

过了一段时间后客户端发出timeout [RST] 报文(windows会弹出异常对话框取消文件传输)

重要的是对于NTFS的格式的U盘是正常的,只有FAT32格式的U盘有这个问题.
2:解决方法
2.1 刚开始我觉得FAT32与NTFS的分区方式不同,可是了解到FAT32分区方式单个文件最大是4G,所以排除U盘本身问题,问题还是出在Samba服务器或者linux系统中(之所以怀疑linux系统是因为我在任何PC机上拷文件到此U盘都没问题)
2.2 然后先debug samba源码,重点注意有关文件size和fat格式处理的相关代码,然后再源码中(\samba-3.0.24\source\smbd\vfs-wrap.c)看见了这个:
int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
{
int result = -;
SMB_STRUCT_STAT st;
char c = ;
SMB_OFF_T currpos; START_PROFILE(syscall_ftruncate); if (lp_strict_allocate(SNUM(fsp->conn))) {
result = strict_allocate_ftruncate(handle, fsp, fd, len);
END_PROFILE(syscall_ftruncate);
return result;
} /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
sys_ftruncate if the system supports it. Then I discovered that
you can have some filesystems that support ftruncate
expansion and some that don't! On Linux fat can't do
ftruncate extend but ext2 can. */ result = sys_ftruncate(fd, len);
if (result == 0)
goto done; /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
extend a file with ftruncate. Provide alternate implementation
for this */
currpos = SMB_VFS_LSEEK(fsp, fd, , SEEK_CUR);
if (currpos == -) {
goto done;
} /* Do an fstat to see if the file is longer than the requested
size in which case the ftruncate above should have
succeeded or shorter, in which case seek to len - 1 and
write 1 byte of zero */
if (SMB_VFS_FSTAT(fsp, fd, &st) == -) {
goto done;
} #ifdef S_ISFIFO
if (S_ISFIFO(st.st_mode)) {
result = ;
goto done;
}
#endif if (st.st_size == len) {
result = ;
goto done;
} if (st.st_size > len) {
/* the sys_ftruncate should have worked */
goto done;
} if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
goto done; if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
goto done; /* Seek to where we were */
if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
goto done;
result = ; done: END_PROFILE(syscall_ftruncate);
return result;
}
红色的两个函数是关键,在调试中发现,sys_ftruncate和SMB_VFS_WRITE在创建大一点的文件时会耗费很多的时间,这也是服务器迟迟不回复客户端SET_FILE_INFO请求的原因。所以将这两个函数屏蔽之后就正常了.
也可以不屏蔽sys_ftruncate,可以将kernel的ftruncate函数实现修改一下:\linux-3.14\fs\fat\file.c 中函数fat_setattr
if (attr->ia_valid & ATTR_SIZE) {
if (attr->ia_size > inode->i_size) {//if current size grenter than old size,extend it
// if we allow this, fat ftruncate extend large size will cause samba wait a long long time.
#if 1
error = -EPERM;
goto out;
#else
error = fat_cont_expand(inode, attr->ia_size);
if (error || attr->ia_valid == ATTR_SIZE)
goto out;
attr->ia_valid &= ~ATTR_SIZE;
#endif
}
}
这样也可以解决问题.
总结:
不管是FAT32还是NTFS都是先接收数据然后写入到文件系统中,所以samba使用ftruncate函数扩展文件到文件系统中,我猜测可能是FAT32是把文件一次性使用fat_setattr函数写到文件系统中(大文件导致写入的时间过长),而NTFS是收到多少写入多少.这样导致FAT32不行而NTFS可行.
Samba共享传输大文件(ex:1G)失败的问题的更多相关文章
- 基于RMI服务传输大文件的完整解决方案
基于RMI服务传输大文件,分为上传和下载两种操作,需要注意的技术点主要有三方面,第一,RMI服务中传输的数据必须是可序列化的.第二,在传输大文件的过程中应该有进度提醒机制,对于大文件传输来说,这点很重 ...
- linux传输大文件
http://dreamway.blog.51cto.com/1281816/1151886 linux传输大文件
- C# 的 WCF文章 消息契约(Message Contract)在流(Stream )传输大文件中的应用
我也遇到同样问题,所以抄下做MARK http://www.cnblogs.com/lmjq/archive/2011/07/19/2110319.html 刚做完一个binding为netTcpBi ...
- WCF 用netTcpbinding,basicHttpBinding 传输大文件
问题:WCF如何传输大文件 方案:主要有几种绑定方式netTcpbinding,basicHttpBinding,wsHttpbinding,设置相关的传输max消息选项,服务端和客户端都要设置,tr ...
- 使用QQ传输大文件
现在在公网上能传输大文件并且稳定支持断点续传的软件非常少了,可以使用qq来做这件事. qq传输单个文件有时候提示不能超过4g有时候提示不能超过60g,没搞明白具体怎么样. 可以使用qq的传输文件夹功能 ...
- php大文件上传失败的原因及解决方法
为什么上传大文件总是失败,上传小文件就没有问题.关于PHP大文件上传失败的原因及解决方法如下: 第1种情况:文件上传时存放文件的临时目录必须是开启的并且是 PHP 进程所有者用户可写的目录.如果未指定 ...
- TCP协议传输大文件读取时候的问题
TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...
- github下载大文件太慢/失败
场景 github下载大文件,使用浏览器下载zip包到本地在下载到1G时失败, 使用 git clone ssh下载速度20k/s以下,已fq. 解决方法(亲测) 1.下载Github Desktop ...
- rsync增量传输大文件优化技巧
问题 rsync用来同步数据非常的好用,特别是增量同步.但是有一种情况如果不增加特定的参数就不是很好用了.比如你要同步多个几十个G的文件,然后网络突然断开了一下,这时候你重新启动增量同步.但是发现等了 ...
随机推荐
- 211. String Permutation【LintCode by java】
Description Given two strings, write a method to decide if one is a permutation of the other. Exampl ...
- 【转】unity 热更新思路和实现
声明:本文介绍的热更新方案是我在网上搜索到的,然后自己修改了一下,相当于是借鉴了别人的思路,加工成了自己的,在此感谢无私分享经验的朋友们. 想要使用热更新技术,需要规划设计好资源比较策略,资源版本,确 ...
- vs_code 快捷键
一般的Ctrl+Shift+P,F1显示命令面板按Ctrl+P快速打开,到文件.Ctrl + Shift + N新窗口/实例Ctrl + Shift + W /关闭窗口实例Ctrl +.用户设置Ctr ...
- Map Reduce Application(Top 10 IDs base on their value)
Top 10 IDs base on their value First , we need to set the reduce to 1. For each map task, it is not ...
- geth账户密码
xiaocong geth账户密码 123 {d6abe909013d8da914ae2a08c9b58e7b76601b39} 账户密码 123456 0x4A7F15104F54dB3214D2F ...
- C Program基础-宏定义
写好c语言,漂亮的宏定义是非常重要的,我们在阅读别人工程时,往往能看到大量的宏定义,宏定义可以增加代码的可读性,也能增加代码的可移植性,一个好的宏定义甚至是一件艺术品.今天我们就来看看宏定义的方方面面 ...
- Python中的print
Python 3.X的print 在Python 3.X中,print是一个内置函数,完整的声明形式如下: print([object, ...][, sep=' '][, end='\n'][, f ...
- scrapy(2)——scrapy爬取新浪微博(单机版)
Sina爬虫教程 Scrapy环境搭建 环境:window10 + python2.7(包含scrapy)+ mongoDB 1.1 安装集成了python2.7的anaconda ana ...
- centos7 nginx端口转发出现502的其中一种原因
在排查了一系列可能的原因后仍无法解决,经资料查阅可能是SELinux造成,SELinux很强大但若配置不当也会造成很多组件无法正常使用,这里直接将其关闭: //打开配置文件 vi /etc/selin ...
- [剑指Offer] 52.正则表达式匹配
题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...