On Wed, 26 Mar 2014 05:21:19 -0700 Jeffrey Layton <jlayton@xxxxxxxxxx> wrote: > On Wed, 26 Mar 2014 21:04:15 +0900 > Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> wrote: > > > Jeff Layton wrote: > > > > Yes, I suggested a customer using CIFS on RHEL6 to use > > > > cache=none or cache=strict , for that customer's system does > > > > not work as expected due to the latter behavior when using > > > > "tail -f" for checking for appended log. > > > > > > Yeah, cache=strict should work much better for that sort of > > > use-case. > > > > > I got another problem where none of cache=none cache=strict > > actimeo=0 helps. > > > > Since "tail -f" does "repeat calling sleep() and fstat() until the > > file size increases" -> "do read() until EOF" -> "call fstat() > > again", "tail -f" prints "file truncated" message and prints some > > portion of already printed lines even though the file size on the > > Samba server never decreased. I expect that the latest fstat() > > returns the up-to-date file size. This behavior is observed on > > 2.6.32-431.11.2.el6.x86_64 and 3.14-rc8. > > > > Steps to reproduce: > > > > ---------- Start of testprog.c ---------- > > /** > > * stdin and stdout must refer a regular file which is shared via > > CIFS. > > * An example is shown below. > > * > > * # mount -t cifs -o > > cache=strict,actimeo=0 //127.0.0.1/path/to/export /path/to/mount > > * $ cc -Wall -O3 -o a.out this_file.c > > * $ ./a.out > /path/to/export/shared_file > > < /path/to/mount/shared_file */ > > #include <stdio.h> > > #include <stdlib.h> > > #include <poll.h> > > #include <sys/stat.h> > > #include <unistd.h> > > > > int main(int argc, char *argv[]) > > { > > unsigned int delay = argc > 1 ? atoi(argv[1]) : 0; > > size_t write_pos = 0; > > size_t read_pos = 0; > > if (ftruncate(1, 0)) > > return 1; > > while (1) { > > struct stat buf; > > char c; > > if (write(1, ".", 1) != 1) > > return 2; > > write_pos++; > > if (fstat(1, &buf)) > > return 3; > > if (buf.st_size != write_pos) > > return 4; > > if (read(0, &c, 1) != 1) > > return 5; > > if (c != '.') > > return 6; > > read_pos++; > > if (delay) > > poll(NULL, 0, delay); > > if (fstat(0, &buf)) > > return 7; > > if (buf.st_size < read_pos) > > fprintf(stderr, "read(%lu) - stat(%lu) = > > %lu\n", read_pos, buf.st_size, read_pos - buf.st_size); > > } > > } > > ---------- End of testprog.c ---------- > > > > Make a CIFS mount on localhost where the Samba server process is > > running. Compile testprog.c and run testprog, with stdin redirected > > to a regular file which is accessed via CIFS and stdout redirected > > to the same regular file which is accessed as a local filesystem. An > > example is shown below. > > > > # mount -t cifs -o cache=none,actimeo=0 //127.0.0.1/home /mnt > > $ cc -Wall -O3 -o testprog testprog.c > > $ ./testprog > ~/shared_file < /mnt/shared_file > > > > According to what testprog.c does, it is expected that nothing is > > printed by testprog process because the bytes read via read() equals > > the bytes obtained via fstat(). However, testprog process prints > > that the bytes read via read() is larger than the bytes obtained via > > fstat(). > > > > The strace on the smbd process reports that CIFS is omitting lstat() > > request after pread() request if lstat() request was done very > > recently. Specifying delay as the command line argument for testprog > > process reduces the possibility of omitting lstat() request. > > (cc'ing samba-technical) > > ...or that samba is omitting it and is sending cached info instead of > doing the lstat() call? I'm not sure if it does that, but I don't > think you should draw too many conclusions about the behavior of > cifs.ko from stracing smbd. > > What may make more sense is to get network captures and analyze the > behavior from that perspective. > ...or maybe it *is* cifs.ko. From cifs_inode_needs_reval: if (!time_in_range(jiffies, cifs_i->time, cifs_i->time + cifs_sb->actimeo)) return true; ...I think though that if cifs_i->time == jiffies and actimeo=0, then that condition will be false. As a quick check, it might be good to add something like this before that if statement and then rerun your test: if (!cifs_sb->actimeo) return true; That should get rid of that particular corner case. -- Jeff Layton <jlayton@xxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html