NAK. I do not see why this is needed. Not all sparse warnings need fixing.
What is so bad about a variable length array that we need to incur kmalloc overhead on each call? I would have thought the CPU overhead of the kmalloc is a lot larger than any CPU overhead of a variable length array... The array size is tiny - basically on all volumes mft_record_size is 1024 and blocksize is either 512 or 1024 thus the array size is either 1 or 2 pointers. The reason it is dynamic is just in case Microsoft change their mind and increase the mft_record_size in a future NTFS/Windows version to something bigger than 1024 bytes, the current code would still cope fine. Note mft_record_size is the "on disk inode size" thus it will never be much bigger and unlikely to ever change from the 1024 really. A very long time ago when NTFS was being developed Microsoft used 2048 bytes but quickly changed it to 1024 as most inodes do not need anywhere near that much space for an inode. Best regards, Anton On 27 Apr 2014, at 11:12, Fabian Frederick <f...@skynet.be> wrote: > fs/ntfs/mft.c:471:33: warning: Variable length array is used. > fs/ntfs/mft.c:676:33: warning: Variable length array is used. > > This is untested. > > Cc: Anton Altaparmakov <an...@tuxera.com> > Cc: Andrew Morton <a...@linux-foundation.org> > Signed-off-by: Fabian Frederick <f...@skynet.be> > --- > fs/ntfs/mft.c | 17 ++++++++++++----- > 1 file changed, 12 insertions(+), 5 deletions(-) > > diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c > index 3014a36..eddb739 100644 > --- a/fs/ntfs/mft.c > +++ b/fs/ntfs/mft.c > @@ -468,7 +468,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned > long mft_no, > struct page *page; > unsigned int blocksize = vol->sb->s_blocksize; > int max_bhs = vol->mft_record_size / blocksize; > - struct buffer_head *bhs[max_bhs]; > + struct buffer_head **bhs; > struct buffer_head *bh, *head; > u8 *kmirr; > runlist_element *rl; > @@ -478,11 +478,14 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const > unsigned long mft_no, > > ntfs_debug("Entering for inode 0x%lx.", mft_no); > BUG_ON(!max_bhs); > - if (unlikely(!vol->mftmirr_ino)) { > + bhs = kmalloc(max_bhs * sizeof(struct buffer_head *), GFP_NOFS); > + if (unlikely(!bhs || !vol->mftmirr_ino)) { > /* This could happen during umount... */ > err = ntfs_sync_mft_mirror_umount(vol, mft_no, m); > - if (likely(!err)) > + if (likely(!err)) { > + kfree(bhs); > return err; > + } > goto err_out; > } > /* Get the page containing the mirror copy of the mft record @m. */ > @@ -632,6 +635,7 @@ err_out: > "after umounting to correct this.", -err); > NVolSetErrors(vol); > } > + kfree(bhs); > return err; > } > > @@ -673,7 +677,7 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD > *m, int sync) > unsigned int blocksize = vol->sb->s_blocksize; > unsigned char blocksize_bits = vol->sb->s_blocksize_bits; > int max_bhs = vol->mft_record_size / blocksize; > - struct buffer_head *bhs[max_bhs]; > + struct buffer_head **bhs; > struct buffer_head *bh, *head; > runlist_element *rl; > unsigned int block_start, block_end, m_start, m_end; > @@ -689,7 +693,8 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD > *m, int sync) > * There is no danger of races since the caller is holding the locks > * for the mft record @m and the page it is in. > */ > - if (!NInoTestClearDirty(ni)) > + bhs = kmalloc(max_bhs * sizeof(struct buffer_head *), GFP_NOFS); > + if (!bhs || !NInoTestClearDirty(ni)) > goto done; > bh = head = page_buffers(page); > BUG_ON(!bh); > @@ -820,6 +825,7 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD > *m, int sync) > goto err_out; > } > done: > + kfree(bhs); > ntfs_debug("Done."); > return 0; > cleanup_out: > @@ -840,6 +846,7 @@ err_out: > err = 0; > } else > NVolSetErrors(vol); > + kfree(bhs); > return err; > } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/