Skip to contentSkip to conversation

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

PATCH New Sven Schnelle 1 participant 1 message Jun 8, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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

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.

---
 fs/afs/file.c  |    3 +++
 fs/afs/rxrpc.c |    2 +- 
 2 files changed, 4 insertions(+), 1 deletions(-)
fs/afs/file.c +0 -0
index 525f7c5..e394b75 100644
@@ -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;
fs/afs/rxrpc.c +1 -1
index bde3f19..fe5e91d 100644
@@ -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();
Signature · 1 line
1.5.5.3