mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
ext4: avoid Y2038 overflow in recently_deleted()
Avoid a 32-bit time overflow in recently_deleted() since i_dtime (inode deletion time) is stored only as a 32-bit value on disk. Since i_dtime isn't used for much beyond a boolean value in e2fsck and is otherwise only used in this function in the kernel, there is no benefit to use more space in the inode for this field on disk. Instead, compare only the relative deletion time with the low 32 bits of the time using the newly-added time_before32() helper, which is similar to time_before() and time_after() for jiffies. Increase RECENTCY_DIRTY to 300s based on Ted's comments about usage experience at Google. Signed-off-by: Andreas Dilger <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]> Reviewed-by: Arnd Bergmann <[email protected]>
This commit is contained in:
parent
fd96b8da68
commit
b5f515735b
2 changed files with 28 additions and 6 deletions
|
|
@ -692,16 +692,17 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
|
|||
* somewhat arbitrary...)
|
||||
*/
|
||||
#define RECENTCY_MIN 5
|
||||
#define RECENTCY_DIRTY 30
|
||||
#define RECENTCY_DIRTY 300
|
||||
|
||||
static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
|
||||
{
|
||||
struct ext4_group_desc *gdp;
|
||||
struct ext4_inode *raw_inode;
|
||||
struct buffer_head *bh;
|
||||
unsigned long dtime, now;
|
||||
int inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
|
||||
int offset, ret = 0, recentcy = RECENTCY_MIN;
|
||||
int inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
|
||||
int offset, ret = 0;
|
||||
int recentcy = RECENTCY_MIN;
|
||||
u32 dtime, now;
|
||||
|
||||
gdp = ext4_get_group_desc(sb, group, NULL);
|
||||
if (unlikely(!gdp))
|
||||
|
|
@ -718,12 +719,18 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino)
|
|||
|
||||
offset = (ino % inodes_per_block) * EXT4_INODE_SIZE(sb);
|
||||
raw_inode = (struct ext4_inode *) (bh->b_data + offset);
|
||||
|
||||
/* i_dtime is only 32 bits on disk, but we only care about relative
|
||||
* times in the range of a few minutes (i.e. long enough to sync a
|
||||
* recently-deleted inode to disk), so using the low 32 bits of the
|
||||
* clock (a 68 year range) is enough, see time_before32() */
|
||||
dtime = le32_to_cpu(raw_inode->i_dtime);
|
||||
now = get_seconds();
|
||||
now = ktime_get_real_seconds();
|
||||
if (buffer_dirty(bh))
|
||||
recentcy += RECENTCY_DIRTY;
|
||||
|
||||
if (dtime && (dtime < now) && (now < dtime + recentcy))
|
||||
if (dtime && time_before32(dtime, now) &&
|
||||
time_before32(now, dtime + recentcy))
|
||||
ret = 1;
|
||||
out:
|
||||
brelse(bh);
|
||||
|
|
|
|||
Loading…
Reference in a new issue