Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / fs / f2fs / inline.c
index a13ffcc..3d143be 100644 (file)
@@ -360,6 +360,10 @@ int make_empty_inline_dir(struct inode *inode, struct inode *parent,
        return 0;
 }
 
+/*
+ * NOTE: ipage is grabbed by caller, but if any error occurs, we should
+ * release ipage in this function.
+ */
 static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage,
                                struct f2fs_inline_dentry *inline_dentry)
 {
@@ -369,8 +373,10 @@ static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage,
        int err;
 
        page = grab_cache_page(dir->i_mapping, 0);
-       if (!page)
+       if (!page) {
+               f2fs_put_page(ipage, 1);
                return -ENOMEM;
+       }
 
        set_new_dnode(&dn, dir, ipage, NULL, 0);
        err = f2fs_reserve_block(&dn, 0);
@@ -378,13 +384,21 @@ static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage,
                goto out;
 
        f2fs_wait_on_page_writeback(page, DATA);
-       zero_user_segment(page, 0, PAGE_CACHE_SIZE);
+       zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE);
 
        dentry_blk = kmap_atomic(page);
 
        /* copy data from inline dentry block to new dentry block */
        memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap,
                                        INLINE_DENTRY_BITMAP_SIZE);
+       memset(dentry_blk->dentry_bitmap + INLINE_DENTRY_BITMAP_SIZE, 0,
+                       SIZE_OF_DENTRY_BITMAP - INLINE_DENTRY_BITMAP_SIZE);
+       /*
+        * we do not need to zero out remainder part of dentry and filename
+        * field, since we have used bitmap for marking the usage status of
+        * them, besides, we can also ignore copying/zeroing reserved space
+        * of dentry block, because them haven't been used so far.
+        */
        memcpy(dentry_blk->dentry, inline_dentry->dentry,
                        sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY);
        memcpy(dentry_blk->filename, inline_dentry->filename,
@@ -434,8 +448,9 @@ int f2fs_add_inline_entry(struct inode *dir, const struct qstr *name,
                                                slots, NR_INLINE_DENTRY);
        if (bit_pos >= NR_INLINE_DENTRY) {
                err = f2fs_convert_inline_dir(dir, ipage, dentry_blk);
-               if (!err)
-                       err = -EAGAIN;
+               if (err)
+                       return err;
+               err = -EAGAIN;
                goto out;
        }