]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
LINUX: Return NULL for afs_linux_raw_open error
authorAndrew Deason <adeason@sinenomine.net>
Mon, 30 Apr 2018 22:30:56 +0000 (17:30 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Sat, 2 Jun 2018 22:18:10 +0000 (18:18 -0400)
Currently, afs_linux_raw_open (and by extension, LINUX's
implementation of osi_UFSOpen) panic when they are unable to open the
given cache file. To allow callers to handle the error more
gracefully, change afs_linux_raw_open and osi_UFSOpen to return NULL
on error, instead of panic'ing. Expand the language a little on the
message logged while we're here, since the system might keep running
after this situation now.

This commit also changes all callers that did not already handle
afs_linux_raw_open/osi_UFSOpen errors to assert on errors, so we still
panic for all situations where we encounter an error. More graceful
behavior will be added in future commits; this commit does not change
the behavior on its own.

An error on opening cache files can legitimately happen when there is
corruption in the filesystem backing the disk cache, but possibly the
easiest way to generate an error is if the filesystem has been
forcibly mounted readonly (which can happen at runtime due to
filesystem corruption or various hardware faults). The latter will
generate -EROFS (-30) errors, but of course other errors are probably
possible.

Reviewed-on: https://gerrit.openafs.org/13045
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit f6af4a155d3636e8f812e40c7169dd8902ae64be)

Change-Id: I5f9a71a96cd9c875f4b024562dfa714f9cc27e2f
Reviewed-on: https://gerrit.openafs.org/13071
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
src/afs/LINUX/osi_file.c
src/afs/LINUX/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_symlink.c
src/afs/VNOPS/afs_vnop_write.c
src/afs/afs_buffer.c
src/afs/afs_dcache.c
src/afs/afs_disconnected.c
src/afs/afs_fetchstore.c
src/afs/afs_init.c
src/afs/afs_segments.c

index 0374c1cce41652db93da706c2e8e2dfe1573e567..7069297a40cba9682361e24768f36b7d5990df19 100644 (file)
@@ -66,8 +66,12 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
 #else
     filp = dentry_open(dget(dp), mntget(afs_cacheMnt), O_RDWR);
 #endif
-    if (IS_ERR(filp))
-       osi_Panic("Can't open file: %d\n", (int) PTR_ERR(filp));
+    if (IS_ERR(filp)) {
+       afs_warn("afs: Cannot open cache file (code %d). Trying to continue, "
+                 "but AFS accesses may return errors or panic the system\n",
+                 (int) PTR_ERR(filp));
+        filp = NULL;
+    }
 
     dput(dp);
 
@@ -99,8 +103,16 @@ osi_UFSOpen(afs_dcache_id_t *ainode)
     memset(afile, 0, sizeof(struct osi_file));
 
     afile->filp = afs_linux_raw_open(ainode);
-    afile->size = i_size_read(FILE_INODE(afile->filp));
+    if (afile->filp) {
+        afile->size = i_size_read(FILE_INODE(afile->filp));
+    }
     AFS_GLOCK();
+
+    if (!afile->filp) {
+        osi_FreeLargeSpace(afile);
+        return NULL;
+    }
+
     afile->offset = 0;
     afile->proc = (int (*)())0;
     return (void *)afile;
index 969a27b271ed3b809f1ddaa462099a5cc09d7886..9a070f28f341881c11f6b845662657b9fe65166a 100644 (file)
@@ -2249,6 +2249,7 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep)
     /* XXX - I suspect we should be locking the inodes before we use them! */
     AFS_GUNLOCK();
     cacheFp = afs_linux_raw_open(&tdc->f.inode);
+    osi_Assert(cacheFp);
     if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) {
        cachefs_noreadpage = 1;
        AFS_GLOCK();
@@ -2677,6 +2678,7 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping,
            AFS_GUNLOCK();
            if (tdc) {
                cacheFp = afs_linux_raw_open(&tdc->f.inode);
+                osi_Assert(cacheFp);
                if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) {
                    cachefs_noreadpage = 1;
                    goto out;
index 1dd461125727948cc8ed35e7d300b0a7edb1c0b4..02ba3b43a131f6ba3d81c9a6b372e3c3c0f55ce5 100644 (file)
@@ -57,6 +57,7 @@ afs_DisconCreateSymlink(struct vcache *avc, char *aname,
     afs_AdjustSize(tdc, len);
     tdc->validPos = len;
     tfile = afs_CFileOpen(&tdc->f.inode);
+    osi_Assert(tfile);
     afs_CFileWrite(tfile, 0, aname, len);
     afs_CFileClose(tfile);
     ReleaseWriteLock(&tdc->lock);
index be6c63adf6abf47214c3806da78147f8048d873e..c7c56dc15cdb3b8353f30b73f9c0acde589547ef 100644 (file)
@@ -335,6 +335,7 @@ afs_write(struct vcache *avc, struct uio *auio, int aio,
            error = code;
            ZapDCE(tdc);        /* bad data */
            cfile = afs_CFileOpen(&tdc->f.inode);
+            osi_Assert(cfile);
            afs_CFileTruncate(cfile, 0);
            afs_CFileClose(cfile);
            afs_AdjustSize(tdc, 0);     /* sets f.chunkSize to 0 */
index 2220ae301c10d3285c6aff4f66f58893cdab0bbb..8a1141d53b8a825dc2ab8b0e1ee0ddc3895b1909 100644 (file)
@@ -239,6 +239,7 @@ DRead(struct dcache *adc, int page, struct DirBuffer *entry)
        return ENOENT; /* past the end */
     }
     tfile = afs_CFileOpen(&adc->f.inode);
+    osi_Assert(tfile);
     code =
        afs_CFileRead(tfile, tb->page * AFS_BUFFER_PAGESIZE, tb->data,
                      AFS_BUFFER_PAGESIZE);
@@ -372,6 +373,7 @@ afs_newslot(struct dcache *adc, afs_int32 apage, struct buffer *lp)
     if (lp->dirty) {
        /* see DFlush for rationale for not getting and locking the dcache */
         tfile = afs_CFileOpen(&lp->inode);
+        osi_Assert(tfile);
        afs_CFileWrite(tfile, lp->page * AFS_BUFFER_PAGESIZE, lp->data,
                       AFS_BUFFER_PAGESIZE);
        lp->dirty = 0;
@@ -461,6 +463,7 @@ DFlushBuffer(struct buffer *ab)
     struct osi_file *tfile;
 
     tfile = afs_CFileOpen(&ab->inode);
+    osi_Assert(tfile);
     afs_CFileWrite(tfile, ab->page * AFS_BUFFER_PAGESIZE,
                   ab->data, AFS_BUFFER_PAGESIZE);
     ab->dirty = 0;     /* Clear the dirty flag */
index 60d2a3106ea2b01d48e8c19bbd46815bce2800c3..321e37f5ac43e8ea0bc61abff535409bf2bab248 100644 (file)
@@ -1188,6 +1188,7 @@ afs_FreeDiscardedDCache(void)
      * Truncate the element to reclaim its space
      */
     tfile = afs_CFileOpen(&tdc->f.inode);
+    osi_Assert(tfile);
     afs_CFileTruncate(tfile, 0);
     afs_CFileClose(tfile);
     afs_AdjustSize(tdc, 0);
@@ -1619,6 +1620,7 @@ afs_AllocDiscardDSlot(afs_int32 lock)
     if ((lock & 2)) {
        /* Truncate the chunk so zeroes get filled properly */
        file = afs_CFileOpen(&tdc->f.inode);
+        osi_Assert(file);
        afs_CFileTruncate(file, 0);
        afs_CFileClose(file);
        afs_AdjustSize(tdc, 0);
@@ -2076,6 +2078,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte,
            /* no data in file to read at this position */
            UpgradeSToWLock(&tdc->lock, 607);
            file = afs_CFileOpen(&tdc->f.inode);
+            osi_Assert(file);
            afs_CFileTruncate(file, 0);
            afs_CFileClose(file);
            afs_AdjustSize(tdc, 0);
@@ -2295,6 +2298,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte,
         */
        DZap(tdc);      /* pages in cache may be old */
        file = afs_CFileOpen(&tdc->f.inode);
+        osi_Assert(file);
        afs_RemoveVCB(&avc->f.fid);
        tdc->f.states |= DWriting;
        tdc->dflags |= DFFetching;
@@ -3616,6 +3620,8 @@ afs_MakeShadowDir(struct vcache *avc, struct dcache *adc)
     /* Open the files. */
     tfile_src = afs_CFileOpen(&adc->f.inode);
     tfile_dst = afs_CFileOpen(&new_dc->f.inode);
+    osi_Assert(tfile_src);
+    osi_Assert(tfile_dst);
 
     /* And now copy dir dcache data into this dcache,
      * 4k at a time.
index 957bf9394173787116c1a0d9a1f90c62e75d01c9..fd6abe2c5569cd8bf83a4ffe185fa10c02192cf2 100644 (file)
@@ -707,6 +707,7 @@ afs_ProcessOpCreate(struct vcache *avc, struct vrequest *areq,
        }
        ObtainReadLock(&tdc->lock);
        tfile = afs_CFileOpen(&tdc->f.inode);
+        osi_Assert(tfile);
        code = afs_CFileRead(tfile, 0, ttargetName, tlen);
        ttargetName[tlen-1] = '\0';
        afs_CFileClose(tfile);
index df31f4348d7d8534226b740af837740adfe1f6b3..c9a73a81be044859f960f984a1bf3baf4239ce7d 100644 (file)
@@ -270,6 +270,7 @@ afs_GenericStoreProc(struct storeOps *ops, void *rock,
     size = tdc->f.chunkBytes;
 
     tfile = afs_CFileOpen(&tdc->f.inode);
+    osi_Assert(tfile);
 
     while ( size > 0 ) {
        code = (*ops->prepare)(rock, size, &tlen);
index acc7bef66d4411b4b42737d7c93394c6b32851e7..6262f928a34d367f0a89d0b20edd8accba228c86 100644 (file)
@@ -330,6 +330,7 @@ afs_InitVolumeInfo(char *afile)
     if (code)
        return code;
     tfile = afs_CFileOpen(&volumeInode);
+    osi_Assert(tfile);
     afs_CFileTruncate(tfile, 0);
     afs_CFileClose(tfile);
     return 0;
index 9992a84a5f756f38e4d40310fa56f808b2deaf12..5a32da4b099a40c0bc4ab53b7a9f4c3eaf2f35cb 100644 (file)
@@ -651,6 +651,7 @@ afs_ExtendSegments(struct vcache *avc, afs_size_t alen, struct vrequest *areq)
            toAdd = AFS_CHUNKTOSIZE(tdc->f.chunk) - offset;
        }
         tfile = afs_CFileOpen(&tdc->f.inode);
+        osi_Assert(tfile);
        while(tdc->validPos < avc->f.m.Length + toAdd) {
             afs_size_t towrite;
 
@@ -819,6 +820,7 @@ afs_TruncateAllSegments(struct vcache *avc, afs_size_t alen,
            UpgradeSToWLock(&tdc->lock, 673);
            tdc->f.states |= DWriting;
            tfile = afs_CFileOpen(&tdc->f.inode);
+            osi_Assert(tfile);
            afs_CFileTruncate(tfile, (afs_int32)newSize);
            afs_CFileClose(tfile);
            afs_AdjustSize(tdc, (afs_int32)newSize);