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的文件,然后网络突然断开了一下,这时候你重新启动增量同步.但是发现等了 ...
随机推荐
- 167. Add Two Numbers【LintCode by java】
Description You have two numbers represented by a linked list, where each node contains a single dig ...
- java 流 文件 IO
Java 流(Stream).文件(File)和IO Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类 ...
- hive使用spark引擎的几种情况
使用spark引擎查询hive有以下几种方式:1>使用spark-sql(spark sql cli)2>使用spark-thrift提交查询sql3>使用hive on spark ...
- 试用Markdown来写东西
试用Markdown来写东西 前言 之前有过一段时间的写东西的习惯,但是后来因为各种原因(主要是因为自己懒惰拖延),所以一直没有写,现在想再开始写,目的很明确,就是发现很多时候,写作能够很好的练习自己 ...
- leetcode个人题解——#17 Letter Combinations of a Phone Number
思路:用深搜遍历九宫格字符串,一开始做的时候发生了引用指向空地址的问题,后来发现是vector不能直接=赋值. class Solution { public: int len; ]={"a ...
- 五:Edits Viewer离线日志查看器
离线日志查看器可以将二进制日志翻译成可读的文件(如XML),只有当hadoop集群停止时才能使用.输入文件支持的类型:XML和二进制.输出文件支持类型:XML 二进制 Stats(标准输出?) ...
- “Hello world!”团队—选题展示
本次选题展示内容: 一.视频展示 链接:http://v.youku.com/v_show/id_XMzA5Mzk5NjYwOA==.html?sharefrom=iphone 视频截图链接:http ...
- Thunder团队第三周 - Scrum会议7
Scrum会议7 小组名称:Thunder 项目名称:i阅app Scrum Master:胡佑蓉 工作照片: 邹双黛在照相,所以图片中没有该同学. 参会成员: 王航:http://www.cnblo ...
- Android开发技巧--Application, ListView排列,格式化浮点数,string.xml占位符,动态引用图片
一. Application用途 1. Application用途 创建Application时机 : Application在启动的时候会调用Application无参的构造方法创建实例; Appl ...
- Python 循环语句和运算符
while 循环 while 条件 : //条件为True时,执行while下带有缩进的语句 语句1 语句2 语句3 for循环 for循环可以用来遍历某一对象(遍历:通俗点说,就是把这个循环中的第一 ...