Skip to content

Commit 2802f94

Browse files
committed
Merge tag 'vfs-7.1-rc1.fat' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull FAT updates from Christian Brauner: "Minor fixes for the fat filesystem" * tag 'vfs-7.1-rc1.fat' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fat: fix stack frame size warnings in KUnit tests fat: add KUnit tests for timestamp conversion helpers
2 parents b7d74ea + 9450576 commit 2802f94

2 files changed

Lines changed: 175 additions & 8 deletions

File tree

fs/fat/fat_test.c

Lines changed: 173 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ struct fat_timestamp_testcase {
2929
int time_offset;
3030
};
3131

32+
struct fat_unix2fat_clamp_testcase {
33+
const char *name;
34+
struct timespec64 ts;
35+
__le16 time;
36+
__le16 date;
37+
u8 cs;
38+
int time_offset;
39+
};
40+
41+
struct fat_truncate_atime_testcase {
42+
const char *name;
43+
struct timespec64 ts;
44+
struct timespec64 expected;
45+
int time_offset;
46+
};
47+
3248
static struct fat_timestamp_testcase time_test_cases[] = {
3349
{
3450
.name = "Earliest possible UTC (1980-01-01 00:00:00)",
@@ -120,13 +136,92 @@ static struct fat_timestamp_testcase time_test_cases[] = {
120136
},
121137
};
122138

139+
static struct fat_unix2fat_clamp_testcase unix2fat_clamp_test_cases[] = {
140+
{
141+
.name = "Clamp to earliest FAT date for 1979-12-31 23:59:59 UTC",
142+
.ts = {.tv_sec = 315532799LL, .tv_nsec = 0L},
143+
.time = cpu_to_le16(0),
144+
.date = cpu_to_le16(33),
145+
.cs = 0,
146+
.time_offset = 0,
147+
},
148+
{
149+
.name = "Clamp after time_offset=-60 pushes 1980-01-01 00:30 UTC below 1980",
150+
.ts = {.tv_sec = 315534600LL, .tv_nsec = 0L},
151+
.time = cpu_to_le16(0),
152+
.date = cpu_to_le16(33),
153+
.cs = 0,
154+
.time_offset = -60,
155+
},
156+
{
157+
.name = "Clamp to latest FAT date for 2108-01-01 00:00:00 UTC",
158+
.ts = {.tv_sec = 4354819200LL, .tv_nsec = 0L},
159+
.time = cpu_to_le16(49021),
160+
.date = cpu_to_le16(65439),
161+
.cs = 199,
162+
.time_offset = 0,
163+
},
164+
{
165+
.name = "Clamp after time_offset=60 pushes 2107-12-31 23:30 UTC beyond 2107",
166+
.ts = {.tv_sec = 4354817400LL, .tv_nsec = 0L},
167+
.time = cpu_to_le16(49021),
168+
.date = cpu_to_le16(65439),
169+
.cs = 199,
170+
.time_offset = 60,
171+
},
172+
};
173+
174+
static struct fat_truncate_atime_testcase truncate_atime_test_cases[] = {
175+
{
176+
.name = "UTC atime truncates to 2004-02-29 00:00:00",
177+
.ts = {.tv_sec = 1078058096LL, .tv_nsec = 789000000L},
178+
.expected = {.tv_sec = 1078012800LL, .tv_nsec = 0L},
179+
.time_offset = 0,
180+
},
181+
{
182+
.name = "time_offset=-60 truncates 2004-02-29 00:30 UTC to previous local midnight",
183+
.ts = {.tv_sec = 1078014645LL, .tv_nsec = 123000000L},
184+
.expected = {.tv_sec = 1077930000LL, .tv_nsec = 0L},
185+
.time_offset = -60,
186+
},
187+
{
188+
.name = "time_offset=60 truncates 2004-02-29 23:30 UTC to next local midnight",
189+
.ts = {.tv_sec = 1078097445LL, .tv_nsec = 123000000L},
190+
.expected = {.tv_sec = 1078095600LL, .tv_nsec = 0L},
191+
.time_offset = 60,
192+
},
193+
};
194+
123195
static void time_testcase_desc(struct fat_timestamp_testcase *t,
124196
char *desc)
125197
{
126198
strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
127199
}
128200

201+
static void unix2fat_clamp_testcase_desc(struct fat_unix2fat_clamp_testcase *t,
202+
char *desc)
203+
{
204+
strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
205+
}
206+
207+
static void truncate_atime_testcase_desc(struct fat_truncate_atime_testcase *t,
208+
char *desc)
209+
{
210+
strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
211+
}
212+
129213
KUNIT_ARRAY_PARAM(fat_time, time_test_cases, time_testcase_desc);
214+
KUNIT_ARRAY_PARAM(fat_unix2fat_clamp, unix2fat_clamp_test_cases,
215+
unix2fat_clamp_testcase_desc);
216+
KUNIT_ARRAY_PARAM(fat_truncate_atime, truncate_atime_test_cases,
217+
truncate_atime_testcase_desc);
218+
219+
static void fat_test_set_time_offset(struct msdos_sb_info *sbi, int time_offset)
220+
{
221+
memset(sbi, 0, sizeof(*sbi));
222+
sbi->options.tz_set = 1;
223+
sbi->options.time_offset = time_offset;
224+
}
130225

131226
static void fat_time_fat2unix_test(struct kunit *test)
132227
{
@@ -135,8 +230,7 @@ static void fat_time_fat2unix_test(struct kunit *test)
135230
struct fat_timestamp_testcase *testcase =
136231
(struct fat_timestamp_testcase *)test->param_value;
137232

138-
fake_sb.options.tz_set = 1;
139-
fake_sb.options.time_offset = testcase->time_offset;
233+
fat_test_set_time_offset(&fake_sb, testcase->time_offset);
140234

141235
fat_time_fat2unix(&fake_sb, &ts,
142236
testcase->time,
@@ -160,29 +254,100 @@ static void fat_time_unix2fat_test(struct kunit *test)
160254
struct fat_timestamp_testcase *testcase =
161255
(struct fat_timestamp_testcase *)test->param_value;
162256

163-
fake_sb.options.tz_set = 1;
164-
fake_sb.options.time_offset = testcase->time_offset;
257+
fat_test_set_time_offset(&fake_sb, testcase->time_offset);
165258

166259
fat_time_unix2fat(&fake_sb, &testcase->ts,
167260
&time, &date, &cs);
168261
KUNIT_EXPECT_EQ_MSG(test,
169-
le16_to_cpu(testcase->time),
170-
le16_to_cpu(time),
262+
testcase->time,
263+
time,
171264
"Time mismatch\n");
172265
KUNIT_EXPECT_EQ_MSG(test,
173-
le16_to_cpu(testcase->date),
174-
le16_to_cpu(date),
266+
testcase->date,
267+
date,
175268
"Date mismatch\n");
176269
KUNIT_EXPECT_EQ_MSG(test,
177270
testcase->cs,
178271
cs,
179272
"Centisecond mismatch\n");
180273
}
181274

275+
static void fat_time_unix2fat_clamp_test(struct kunit *test)
276+
{
277+
static struct msdos_sb_info fake_sb;
278+
__le16 date, time;
279+
u8 cs;
280+
struct fat_unix2fat_clamp_testcase *testcase =
281+
(struct fat_unix2fat_clamp_testcase *)test->param_value;
282+
283+
fat_test_set_time_offset(&fake_sb, testcase->time_offset);
284+
285+
fat_time_unix2fat(&fake_sb, &testcase->ts, &time, &date, &cs);
286+
KUNIT_EXPECT_EQ_MSG(test,
287+
testcase->time,
288+
time,
289+
"Clamped time mismatch\n");
290+
KUNIT_EXPECT_EQ_MSG(test,
291+
testcase->date,
292+
date,
293+
"Clamped date mismatch\n");
294+
KUNIT_EXPECT_EQ_MSG(test,
295+
testcase->cs,
296+
cs,
297+
"Clamped centisecond mismatch\n");
298+
}
299+
300+
static void fat_time_unix2fat_no_csec_test(struct kunit *test)
301+
{
302+
static struct msdos_sb_info fake_sb;
303+
struct timespec64 ts = {
304+
.tv_sec = 946684799LL,
305+
.tv_nsec = 0L,
306+
};
307+
__le16 date, time;
308+
309+
fat_test_set_time_offset(&fake_sb, 0);
310+
311+
fat_time_unix2fat(&fake_sb, &ts, &time, &date, NULL);
312+
KUNIT_EXPECT_EQ_MSG(test,
313+
49021,
314+
le16_to_cpu(time),
315+
"Time mismatch without centiseconds\n");
316+
KUNIT_EXPECT_EQ_MSG(test,
317+
10143,
318+
le16_to_cpu(date),
319+
"Date mismatch without centiseconds\n");
320+
}
321+
322+
static void fat_truncate_atime_test(struct kunit *test)
323+
{
324+
static struct msdos_sb_info fake_sb;
325+
struct timespec64 actual;
326+
struct fat_truncate_atime_testcase *testcase =
327+
(struct fat_truncate_atime_testcase *)test->param_value;
328+
329+
fat_test_set_time_offset(&fake_sb, testcase->time_offset);
330+
331+
actual = fat_truncate_atime(&fake_sb, &testcase->ts);
332+
KUNIT_EXPECT_EQ_MSG(test,
333+
testcase->expected.tv_sec,
334+
actual.tv_sec,
335+
"Atime truncation seconds mismatch\n");
336+
KUNIT_EXPECT_EQ_MSG(test,
337+
testcase->expected.tv_nsec,
338+
actual.tv_nsec,
339+
"Atime truncation nanoseconds mismatch\n");
340+
}
341+
182342
static struct kunit_case fat_test_cases[] = {
183343
KUNIT_CASE(fat_checksum_test),
184344
KUNIT_CASE_PARAM(fat_time_fat2unix_test, fat_time_gen_params),
185345
KUNIT_CASE_PARAM(fat_time_unix2fat_test, fat_time_gen_params),
346+
KUNIT_CASE_PARAM(fat_time_unix2fat_clamp_test,
347+
fat_unix2fat_clamp_gen_params),
348+
KUNIT_CASE(fat_time_unix2fat_no_csec_test),
349+
KUNIT_CASE_PARAM(fat_truncate_atime_test,
350+
fat_truncate_atime_gen_params),
186351
{},
187352
};
188353

fs/fat/misc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ struct timespec64 fat_truncate_atime(const struct msdos_sb_info *sbi,
297297

298298
return (struct timespec64){ seconds, 0 };
299299
}
300+
/* Export fat_truncate_atime() for the fat_test KUnit tests. */
301+
EXPORT_SYMBOL_GPL(fat_truncate_atime);
300302

301303
/*
302304
* Update the in-inode atime and/or mtime after truncating the timestamp to the

0 commit comments

Comments
 (0)