[PATCH] afs: don't SetPageError() if afs_readpage is interrupted by a signal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi David,

while browsing with mc (midnight commander) my AFS filesystem, i've been
seeing a lot of empty directories (which aren't empty on the server, of
course). After looking into the code, i recognized that the
afs_wait_for_call_to_complete() function was interrupted because mc has
received a signal before the response from the fileserver arrived, and
returned with -EINTR.

That would be not a big problem, as the system call may be restarted,
but this doesn't work in this case because the page is marked as error
in the page cache, and so even the retry returns with -EIO.

I've changed the code with the attached patch, which works for me. As i
have not much insight in the filesystem code, is this a correct fix? If
not, how would a proper solution look like?

Thanks,

Sven.

If a signal is delivered to a process who is reading data from AFS,
the Pagecache Entry is marked with error - so even if the process
retries the operation after finishing signal handling, it will fail. So we
should only mark the page with error if there was an error on the remote side.
also change EINTR to ERESTARTSYS, so the system call will be restarted.

Signed-off-by: Sven Schnelle <svens@xxxxxxxxxxxxxx>

---
 fs/afs/file.c  |    3 +++
 fs/afs/rxrpc.c |    2 +- 
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/fs/afs/file.c b/fs/afs/file.c
index 525f7c5..e394b75 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -201,6 +201,8 @@ static int afs_readpage(struct file *file, struct
page *page)
 #ifdef AFS_CACHING_SUPPORT
                        cachefs_uncache_page(vnode->cache, page);
 #endif
+                       if (ret == -ERESTARTSYS)
+                               goto error_restart;
                        goto error;
                }  
 
@@ -226,6 +228,7 @@ static int afs_readpage(struct file *file, struct
page *page)
 
 error:
        SetPageError(page);
+error_restart:
        unlock_page(page);
        _leave(" = %d", ret);
        return ret;
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index bde3f19..fe5e91d 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -541,7 +541,7 @@ static int afs_wait_for_call_to_complete(struct
        afs_call *call)
                ret = call->error;
                if (call->state >= AFS_CALL_COMPLETE)
                        break;
-               ret = -EINTR;
+               ret = -ERESTARTSYS;
                if (signal_pending(current))
                        break;
                schedule();
-- 
1.5.5.3
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux