|
|
@@ -1097,8 +1097,11 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
|
|
|
err = -ENOMEM;
|
|
|
goto error;
|
|
|
}
|
|
|
+ /* Avoid race with userspace read via bdev */
|
|
|
+ lock_buffer(bhs[n]);
|
|
|
memset(bhs[n]->b_data, 0, sb->s_blocksize);
|
|
|
set_buffer_uptodate(bhs[n]);
|
|
|
+ unlock_buffer(bhs[n]);
|
|
|
mark_buffer_dirty_inode(bhs[n], dir);
|
|
|
|
|
|
n++;
|
|
|
@@ -1155,6 +1158,8 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
|
|
|
fat_time_unix2fat(sbi, ts, &time, &date, &time_cs);
|
|
|
|
|
|
de = (struct msdos_dir_entry *)bhs[0]->b_data;
|
|
|
+ /* Avoid race with userspace read via bdev */
|
|
|
+ lock_buffer(bhs[0]);
|
|
|
/* filling the new directory slots ("." and ".." entries) */
|
|
|
memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME);
|
|
|
memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME);
|
|
|
@@ -1177,6 +1182,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
|
|
|
de[0].size = de[1].size = 0;
|
|
|
memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
|
|
|
set_buffer_uptodate(bhs[0]);
|
|
|
+ unlock_buffer(bhs[0]);
|
|
|
mark_buffer_dirty_inode(bhs[0], dir);
|
|
|
|
|
|
err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE);
|
|
|
@@ -1234,11 +1240,14 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
|
|
|
|
|
|
/* fill the directory entry */
|
|
|
copy = min(size, sb->s_blocksize);
|
|
|
+ /* Avoid race with userspace read via bdev */
|
|
|
+ lock_buffer(bhs[n]);
|
|
|
memcpy(bhs[n]->b_data, slots, copy);
|
|
|
- slots += copy;
|
|
|
- size -= copy;
|
|
|
set_buffer_uptodate(bhs[n]);
|
|
|
+ unlock_buffer(bhs[n]);
|
|
|
mark_buffer_dirty_inode(bhs[n], dir);
|
|
|
+ slots += copy;
|
|
|
+ size -= copy;
|
|
|
if (!size)
|
|
|
break;
|
|
|
n++;
|