Whamcloud - gitweb
LU-12593 osd: up i_append_sem during errors 06/37406/3
authorAlexander Boyko <c17825@cray.com>
Mon, 3 Feb 2020 09:24:40 +0000 (04:24 -0500)
committerOleg Drokin <green@whamcloud.com>
Sat, 8 Feb 2020 04:07:03 +0000 (04:07 +0000)
There is a potential leak of i_append_sem during errors for
buffer head read and ldiskfs_joural_get_write_access() at
osd_ldiskfs_write_record().
The patch adds up(i_append_sem) for errors paths.

Fixes: f832a7dc33c6 ("LU-12593 osd: zeroing a freshly allocated block buffer")
Signed-off-by: Alexander Boyko <c17825@cray.com>
Change-Id: I245d0c45af03519c66b75731e5d57f42de41fe95
Reviewed-on: https://review.whamcloud.com/37406
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/osd-ldiskfs/osd_io.c

index 9095b51..64b995d 100644 (file)
@@ -1696,7 +1696,7 @@ static int osd_ldiskfs_write_record(struct dt_object *dt, void *buf,
         int                 boffs;
         int                 dirty_inode = 0;
        struct ldiskfs_inode_info *ei = LDISKFS_I(inode);
         int                 boffs;
         int                 dirty_inode = 0;
        struct ldiskfs_inode_info *ei = LDISKFS_I(inode);
-       bool create, sparse;
+       bool create, sparse, sync = false;
 
        if (write_NUL) {
                /*
 
        if (write_NUL) {
                /*
@@ -1714,7 +1714,6 @@ static int osd_ldiskfs_write_record(struct dt_object *dt, void *buf,
 
        while (bufsize > 0) {
                int credits = handle->h_buffer_credits;
 
        while (bufsize > 0) {
                int credits = handle->h_buffer_credits;
-               bool sync;
                unsigned long last_block = (new_size == 0) ? 0 :
                                           (new_size - 1) >> inode->i_blkbits;
 
                unsigned long last_block = (new_size == 0) ? 0 :
                                           (new_size - 1) >> inode->i_blkbits;
 
@@ -1751,8 +1750,10 @@ static int osd_ldiskfs_write_record(struct dt_object *dt, void *buf,
                        bh = __ldiskfs_bread(handle, inode, block, flags);
                        create = true;
                } else {
                        bh = __ldiskfs_bread(handle, inode, block, flags);
                        create = true;
                } else {
-                       if (sync)
+                       if (sync) {
                                up(&ei->i_append_sem);
                                up(&ei->i_append_sem);
+                               sync = false;
+                       }
                        create = false;
                }
                if (IS_ERR_OR_NULL(bh)) {
                        create = false;
                }
                if (IS_ERR_OR_NULL(bh)) {
@@ -1781,8 +1782,10 @@ static int osd_ldiskfs_write_record(struct dt_object *dt, void *buf,
                         boffs, size, (unsigned long)bh->b_size);
                if (create) {
                        memset(bh->b_data, 0, bh->b_size);
                         boffs, size, (unsigned long)bh->b_size);
                if (create) {
                        memset(bh->b_data, 0, bh->b_size);
-                       if (sync)
+                       if (sync) {
                                up(&ei->i_append_sem);
                                up(&ei->i_append_sem);
+                               sync = false;
+                       }
                }
                memcpy(bh->b_data + boffs, buf, size);
                err = ldiskfs_handle_dirty_metadata(handle, NULL, bh);
                }
                memcpy(bh->b_data + boffs, buf, size);
                err = ldiskfs_handle_dirty_metadata(handle, NULL, bh);
@@ -1795,8 +1798,11 @@ static int osd_ldiskfs_write_record(struct dt_object *dt, void *buf,
                 bufsize -= size;
                 buf += size;
         }
                 bufsize -= size;
                 buf += size;
         }
-        if (bh)
-                brelse(bh);
+       if (sync)
+               up(&ei->i_append_sem);
+
+       if (bh)
+               brelse(bh);
 
        if (write_NUL)
                --new_size;
 
        if (write_NUL)
                --new_size;