From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeff Layton Subject: Re: blocking write() after disconnecting cifs server Date: Thu, 2 Jan 2014 14:31:57 -0500 Message-ID: <20140102143157.3232068c@corrin.poochiereds.net> References: <20131223054643.4f6c06c9@tlielax.poochiereds.net> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: mail654-Mmb7MZpHnFY@public.gmane.org Return-path: In-Reply-To: Sender: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org List-ID: On Thu, 2 Jan 2014 17:04:27 +0100 (CET) mail654-Mmb7MZpHnFY@public.gmane.org wrote: > > > write() from cifs kernel driver blocks when disconnecting the cif= s server. The blocking call didn't return after 30 minutes. Client and = server are connected via a switch and server's LAN cable is unplugged d= uring the write call. I use kernel 3.11.8 and mounted without "hard" op= tion. > > >=20 > > > Is there a possibility for an non-blocking write() without using = O_SYNC or "directio" mount option? > > >=20 > > > Way to reproduce the scenario: Below is a sample program which ca= lls write() in a loop. The error messages appear when unplugging the ca= ble during this loop. > > >=20 > > > Kind regards, > > > Hagen > > >=20 > > > CIFS VFS: sends on sock ffff88003710c280 stuck for 15 seconds > > > CIFS VFS: Error -11 sending data on socket to server > > >=20 > > > #include > > > #include > > > int main () { > > > =C2=A0 const int size =3D 100000; > > > =C2=A0 char buffer[size]; > > > =C2=A0 std::ofstream outfile("/mnt/new.bin",std::ofstream::binary= ); > > > =C2=A0 if (!outfile.is_open()) > > > =C2=A0 { > > > =C2=A0=C2=A0=C2=A0 return 1; > > > =C2=A0 } > > > =C2=A0 for (int idx=3D0; idx<10000 && outfile.good(); idx++) > > > =C2=A0 { > > > =C2=A0=C2=A0=C2=A0 outfile.write(buffer,size); > > > =C2=A0=C2=A0=C2=A0 std::cout << "written, size=3D" << size << std= ::endl; > > > =C2=A0 } > > > =C2=A0 std::cout << "finished " << outfile.good() << std::endl; > > > =C2=A0 outfile.close(); > > > =C2=A0 return 0; > > > } > >=20 > > A hang of that length is unexpected. If you're able to reproduce th= is, > > can you get the stack from the task issuing the write at the time? > >=20 > > $ cat /proc//stack > >=20 > > That might give us a clue as to what it's doing. >=20 > [] balance_dirty_pages.isra.19+0x4ac/0x55c > [] balance_dirty_pages_ratelimited+0xeb/0x110 > [] generic_perform_write+0x16a/0x210 > [] generic_file_buffered_write+0x5d/0x90 > [] __generic_file_aio_write+0x1b6/0x3b0 > [] generic_file_aio_write+0x69/0xd0 > [] cifs_strict_writev+0xa5/0xd0 [cifs] > [] do_sync_readv_writev+0x65/0x90 > [] do_readv_writev+0xd2/0x2b0 > [] vfs_writev+0x3c/0x50 > [] SyS_writev+0x52/0xc0 > [] tracesys+0xe1/0xe6 > [] 0xffffffffffffffff >=20 Looks like it's stuck in dirty page throttling. What's likely happening is that you have a bunch of dirty pages when you go to pull the cable. At that point the system is trying to flush the pages so that this task can try to dirty more of them. What *should* happen (at least if this is a soft mount) is that the writeback of those pages eventually times out, the pages get their error bit set and eventually the write() syscalls go through. Have you tried stracing this and are able to tell that the write syscall never returns in this situation? Is it possible that the write() syscalls are returning, albeit slowly? --=20 Jeff Layton