| Subject: | Directory "corruption" problems after dread-do-validation-20041012 |
When using an openafs with dread-do-validation-20041012 applied,
sometimes, when a client makes a change to a directory that results in
the directory being extended, the client may experience apparent
directory corruption or truncated directory listings until the directory
is flushed from the cache or an operation by another client results in
the callback being broken.
This is because the local modification of the directory did not change
the size of the directory listed in the dcache object, and so DRead()
will only read up to the old directory size.
The following hack will fix this problem, but is probably not portable
to non-linux platforms:
Index: src/afs/afs_buffer.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_buffer.c,v
retrieving revision 1.17
diff -u -d -r1.17 afs_buffer.c
--- src/afs/afs_buffer.c 13 Oct 2004 00:51:00 -0000 1.17
+++ src/afs/afs_buffer.c 21 Oct 2004 21:19:03 -0000
@@ -10,6 +10,7 @@
#include <afsconfig.h>
#include "afs/param.h"
+#include <stddef.h>
RCSID
("$Header: /cvs/openafs/src/afs/afs_buffer.c,v 1.17 2004/10/13
00:51:00 shadow Exp $");
@@ -487,6 +488,9 @@
DNew(register struct fcache * fid, register int page)
{
/* Same as read, only do *not* even try to read the page, since it
probably doesn't exist. */
+#if 1 /* HACK */
+ struct dcache *tdc = (struct dcache *)(((char *)fid) -
offsetof(struct dcache, f));
+#endif
register struct buffer *tb;
AFS_STATCNT(DNew);
MObtainWriteLock(&afs_bufferLock, 264);
@@ -494,6 +498,12 @@
MReleaseWriteLock(&afs_bufferLock);
return 0;
}
+#if 1 /* HACK */
+ if ((page + 1) * AFS_BUFFER_PAGESIZE > fid->chunkBytes) {
+ afs_AdjustSize(tdc, (page + 1) * AFS_BUFFER_PAGESIZE);
+ afs_WriteDCache(tdc, 1);
+ }
+#endif
MObtainWriteLock(&tb->lock, 265);
MReleaseWriteLock(&afs_bufferLock);
tb->lockers++;
It may be that the correct solution involves using a struct dcache
instead of an fcache as the opaque directory handle. We will just need
to make sure that locking continues to be handled consistently. (either
DRead/DNew/DFlush are responsible for locking dcache's or, as now, the
callers of afs_dir_* are...)
sometimes, when a client makes a change to a directory that results in
the directory being extended, the client may experience apparent
directory corruption or truncated directory listings until the directory
is flushed from the cache or an operation by another client results in
the callback being broken.
This is because the local modification of the directory did not change
the size of the directory listed in the dcache object, and so DRead()
will only read up to the old directory size.
The following hack will fix this problem, but is probably not portable
to non-linux platforms:
Index: src/afs/afs_buffer.c
===================================================================
RCS file: /cvs/openafs/src/afs/afs_buffer.c,v
retrieving revision 1.17
diff -u -d -r1.17 afs_buffer.c
--- src/afs/afs_buffer.c 13 Oct 2004 00:51:00 -0000 1.17
+++ src/afs/afs_buffer.c 21 Oct 2004 21:19:03 -0000
@@ -10,6 +10,7 @@
#include <afsconfig.h>
#include "afs/param.h"
+#include <stddef.h>
RCSID
("$Header: /cvs/openafs/src/afs/afs_buffer.c,v 1.17 2004/10/13
00:51:00 shadow Exp $");
@@ -487,6 +488,9 @@
DNew(register struct fcache * fid, register int page)
{
/* Same as read, only do *not* even try to read the page, since it
probably doesn't exist. */
+#if 1 /* HACK */
+ struct dcache *tdc = (struct dcache *)(((char *)fid) -
offsetof(struct dcache, f));
+#endif
register struct buffer *tb;
AFS_STATCNT(DNew);
MObtainWriteLock(&afs_bufferLock, 264);
@@ -494,6 +498,12 @@
MReleaseWriteLock(&afs_bufferLock);
return 0;
}
+#if 1 /* HACK */
+ if ((page + 1) * AFS_BUFFER_PAGESIZE > fid->chunkBytes) {
+ afs_AdjustSize(tdc, (page + 1) * AFS_BUFFER_PAGESIZE);
+ afs_WriteDCache(tdc, 1);
+ }
+#endif
MObtainWriteLock(&tb->lock, 265);
MReleaseWriteLock(&afs_bufferLock);
tb->lockers++;
It may be that the correct solution involves using a struct dcache
instead of an fcache as the opaque directory handle. We will just need
to make sure that locking continues to be handled consistently. (either
DRead/DNew/DFlush are responsible for locking dcache's or, as now, the
callers of afs_dir_* are...)