Merge tag 'for-6.18/hpfs-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull hpfs updates from Mikulas Patocka:

 - Avoid -Wflex-array-member-not-at-end warnings

 - Replace simple_strtoul with kstrtoint

 - Fix error code for new_inode() failure

* tag 'for-6.18/hpfs-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  fs/hpfs: Fix error code for new_inode() failure in mkdir/create/mknod/symlink
  hpfs: Replace simple_strtoul with kstrtoint in hpfs_parse_param
  fs: hpfs: Avoid multiple -Wflex-array-member-not-at-end warnings
This commit is contained in:
Linus Torvalds
2025-10-10 14:06:02 -07:00
7 changed files with 75 additions and 52 deletions

View File

@@ -27,7 +27,7 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode,
a = le32_to_cpu(btree->u.internal[i].down); a = le32_to_cpu(btree->u.internal[i].down);
brelse(bh); brelse(bh);
if (!(anode = hpfs_map_anode(s, a, &bh))) return -1; if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
goto go_down; goto go_down;
} }
hpfs_error(s, "sector %08x not found in internal anode %08x", sec, a); hpfs_error(s, "sector %08x not found in internal anode %08x", sec, a);
@@ -69,12 +69,13 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
int n; int n;
unsigned fs; unsigned fs;
int c1, c2 = 0; int c1, c2 = 0;
if (fnod) { if (fnod) {
if (!(fnode = hpfs_map_fnode(s, node, &bh))) return -1; if (!(fnode = hpfs_map_fnode(s, node, &bh))) return -1;
btree = &fnode->btree; btree = GET_BTREE_PTR(&fnode->btree);
} else { } else {
if (!(anode = hpfs_map_anode(s, node, &bh))) return -1; if (!(anode = hpfs_map_anode(s, node, &bh))) return -1;
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
} }
a = node; a = node;
go_down: go_down:
@@ -91,7 +92,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
if (hpfs_sb(s)->sb_chk) if (hpfs_sb(s)->sb_chk)
if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_add_sector_to_btree #1")) return -1; if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_add_sector_to_btree #1")) return -1;
if (!(anode = hpfs_map_anode(s, a, &bh))) return -1; if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
goto go_down; goto go_down;
} }
if (n >= 0) { if (n >= 0) {
@@ -151,7 +152,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
} }
brelse(bh); brelse(bh);
bh = bh1; bh = bh1;
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
} }
btree->n_free_nodes--; n = btree->n_used_nodes++; btree->n_free_nodes--; n = btree->n_used_nodes++;
le16_add_cpu(&btree->first_free, 12); le16_add_cpu(&btree->first_free, 12);
@@ -168,10 +169,10 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
if (hpfs_stop_cycles(s, up, &c1, &c2, "hpfs_add_sector_to_btree #2")) return -1; if (hpfs_stop_cycles(s, up, &c1, &c2, "hpfs_add_sector_to_btree #2")) return -1;
if (up != node || !fnod) { if (up != node || !fnod) {
if (!(anode = hpfs_map_anode(s, up, &bh))) return -1; if (!(anode = hpfs_map_anode(s, up, &bh))) return -1;
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
} else { } else {
if (!(fnode = hpfs_map_fnode(s, up, &bh))) return -1; if (!(fnode = hpfs_map_fnode(s, up, &bh))) return -1;
btree = &fnode->btree; btree = GET_BTREE_PTR(&fnode->btree);
} }
if (btree->n_free_nodes) { if (btree->n_free_nodes) {
btree->n_free_nodes--; n = btree->n_used_nodes++; btree->n_free_nodes--; n = btree->n_used_nodes++;
@@ -206,8 +207,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
anode->btree.n_used_nodes = 1; anode->btree.n_used_nodes = 1;
anode->btree.n_free_nodes = 59; anode->btree.n_free_nodes = 59;
anode->btree.first_free = cpu_to_le16(16); anode->btree.first_free = cpu_to_le16(16);
anode->btree.u.internal[0].down = cpu_to_le32(a); GET_BTREE_PTR(&anode->btree)->u.internal[0].down = cpu_to_le32(a);
anode->btree.u.internal[0].file_secno = cpu_to_le32(-1); GET_BTREE_PTR(&anode->btree)->u.internal[0].file_secno = cpu_to_le32(-1);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
if ((anode = hpfs_map_anode(s, a, &bh))) { if ((anode = hpfs_map_anode(s, a, &bh))) {
@@ -229,20 +230,20 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi
brelse(bh2); brelse(bh2);
return -1; return -1;
} }
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
} else { } else {
if (!(fnode = hpfs_map_fnode(s, node, &bh))) { if (!(fnode = hpfs_map_fnode(s, node, &bh))) {
brelse(bh2); brelse(bh2);
return -1; return -1;
} }
btree = &fnode->btree; btree = GET_BTREE_PTR(&fnode->btree);
} }
ranode->up = cpu_to_le32(node); ranode->up = cpu_to_le32(node);
memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free)); memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free));
if (fnod) if (fnod)
ranode->btree.flags |= BP_fnode_parent; ranode->btree.flags |= BP_fnode_parent;
ranode->btree.n_free_nodes = (bp_internal(&ranode->btree) ? 60 : 40) - ranode->btree.n_used_nodes; GET_BTREE_PTR(&ranode->btree)->n_free_nodes = (bp_internal(GET_BTREE_PTR(&ranode->btree)) ? 60 : 40) - GET_BTREE_PTR(&ranode->btree)->n_used_nodes;
if (bp_internal(&ranode->btree)) for (n = 0; n < ranode->btree.n_used_nodes; n++) { if (bp_internal(GET_BTREE_PTR(&ranode->btree))) for (n = 0; n < GET_BTREE_PTR(&ranode->btree)->n_used_nodes; n++) {
struct anode *unode; struct anode *unode;
if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) { if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) {
unode->up = cpu_to_le32(ra); unode->up = cpu_to_le32(ra);
@@ -291,7 +292,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
if (hpfs_stop_cycles(s, ano, &d1, &d2, "hpfs_remove_btree #1")) if (hpfs_stop_cycles(s, ano, &d1, &d2, "hpfs_remove_btree #1"))
return; return;
if (!(anode = hpfs_map_anode(s, ano, &bh))) return; if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
btree1 = &anode->btree; btree1 = GET_BTREE_PTR(&anode->btree);
level++; level++;
pos = 0; pos = 0;
} }
@@ -307,7 +308,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
ano = le32_to_cpu(anode->up); ano = le32_to_cpu(anode->up);
if (--level) { if (--level) {
if (!(anode = hpfs_map_anode(s, ano, &bh))) return; if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
btree1 = &anode->btree; btree1 = GET_BTREE_PTR(&anode->btree);
} else btree1 = btree; } else btree1 = btree;
for (i = 0; i < btree1->n_used_nodes; i++) { for (i = 0; i < btree1->n_used_nodes; i++) {
if (le32_to_cpu(btree1->u.internal[i].down) == oano) { if (le32_to_cpu(btree1->u.internal[i].down) == oano) {
@@ -332,7 +333,7 @@ static secno anode_lookup(struct super_block *s, anode_secno a, unsigned sec)
struct anode *anode; struct anode *anode;
struct buffer_head *bh; struct buffer_head *bh;
if (!(anode = hpfs_map_anode(s, a, &bh))) return -1; if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
return hpfs_bplus_lookup(s, NULL, &anode->btree, sec, bh); return hpfs_bplus_lookup(s, NULL, GET_BTREE_PTR(&anode->btree), sec, bh);
} }
int hpfs_ea_read(struct super_block *s, secno a, int ano, unsigned pos, int hpfs_ea_read(struct super_block *s, secno a, int ano, unsigned pos,
@@ -388,7 +389,7 @@ void hpfs_ea_remove(struct super_block *s, secno a, int ano, unsigned len)
struct buffer_head *bh; struct buffer_head *bh;
if (ano) { if (ano) {
if (!(anode = hpfs_map_anode(s, a, &bh))) return; if (!(anode = hpfs_map_anode(s, a, &bh))) return;
hpfs_remove_btree(s, &anode->btree); hpfs_remove_btree(s, GET_BTREE_PTR(&anode->btree));
brelse(bh); brelse(bh);
hpfs_free_sectors(s, a, 1); hpfs_free_sectors(s, a, 1);
} else hpfs_free_sectors(s, a, (len + 511) >> 9); } else hpfs_free_sectors(s, a, (len + 511) >> 9);
@@ -407,10 +408,10 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
int c1, c2 = 0; int c1, c2 = 0;
if (fno) { if (fno) {
if (!(fnode = hpfs_map_fnode(s, f, &bh))) return; if (!(fnode = hpfs_map_fnode(s, f, &bh))) return;
btree = &fnode->btree; btree = GET_BTREE_PTR(&fnode->btree);
} else { } else {
if (!(anode = hpfs_map_anode(s, f, &bh))) return; if (!(anode = hpfs_map_anode(s, f, &bh))) return;
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
} }
if (!secs) { if (!secs) {
hpfs_remove_btree(s, btree); hpfs_remove_btree(s, btree);
@@ -448,7 +449,7 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
if (hpfs_stop_cycles(s, node, &c1, &c2, "hpfs_truncate_btree")) if (hpfs_stop_cycles(s, node, &c1, &c2, "hpfs_truncate_btree"))
return; return;
if (!(anode = hpfs_map_anode(s, node, &bh))) return; if (!(anode = hpfs_map_anode(s, node, &bh))) return;
btree = &anode->btree; btree = GET_BTREE_PTR(&anode->btree);
} }
nodes = btree->n_used_nodes + btree->n_free_nodes; nodes = btree->n_used_nodes + btree->n_free_nodes;
for (i = 0; i < btree->n_used_nodes; i++) for (i = 0; i < btree->n_used_nodes; i++)
@@ -485,7 +486,7 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno)
struct extended_attribute *ea; struct extended_attribute *ea;
struct extended_attribute *ea_end; struct extended_attribute *ea_end;
if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return; if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return;
if (!fnode_is_dir(fnode)) hpfs_remove_btree(s, &fnode->btree); if (!fnode_is_dir(fnode)) hpfs_remove_btree(s, GET_BTREE_PTR(&fnode->btree));
else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno)); else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno));
ea_end = fnode_end_ea(fnode); ea_end = fnode_end_ea(fnode);
for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))

View File

@@ -41,7 +41,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
struct buffer_head *bh; struct buffer_head *bh;
struct anode *anode; struct anode *anode;
if ((anode = hpfs_map_anode(s, a, &bh))) { if ((anode = hpfs_map_anode(s, a, &bh))) {
hpfs_remove_btree(s, &anode->btree); hpfs_remove_btree(s, GET_BTREE_PTR(&anode->btree));
brelse(bh); brelse(bh);
hpfs_free_sectors(s, a, 1); hpfs_free_sectors(s, a, 1);
} }

View File

@@ -51,7 +51,9 @@ static secno hpfs_bmap(struct inode *inode, unsigned file_secno, unsigned *n_sec
return hpfs_inode->i_disk_sec + n; return hpfs_inode->i_disk_sec + n;
} }
if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0; if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0;
disk_secno = hpfs_bplus_lookup(inode->i_sb, inode, &fnode->btree, file_secno, bh); disk_secno = hpfs_bplus_lookup(inode->i_sb, inode,
GET_BTREE_PTR(&fnode->btree),
file_secno, bh);
if (disk_secno == -1) return 0; if (disk_secno == -1) return 0;
if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0; if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0;
n = file_secno - hpfs_inode->i_file_sec; n = file_secno - hpfs_inode->i_file_sec;

View File

@@ -394,27 +394,45 @@ enum {
BP_binary_search = 0x40, BP_binary_search = 0x40,
BP_internal = 0x80 BP_internal = 0x80
}; };
/**
* GET_BTREE_PTR() - Get a pointer to struct bplus_header
*
* Wrapper around container_of() to retrieve a pointer to struct
* bplus_header from a pointer to struct bplus_header_fixed.
*
* @ptr: Pointer to struct bplus_header_fixed.
*
*/
#define GET_BTREE_PTR(ptr) \
container_of(ptr, struct bplus_header, __hdr)
struct bplus_header struct bplus_header
{ {
u8 flags; /* bit 0 - high bit of first free entry offset /* New members MUST be added within the struct_group() macro below. */
struct_group_tagged(bplus_header_fixed, __hdr,
u8 flags; /* bit 0 - high bit of first free entry offset
bit 5 - we're pointed to by an fnode, bit 5 - we're pointed to by an fnode,
the data btree or some ea or the the data btree or some ea or the
main ea bootage pointer ea_secno main ea bootage pointer ea_secno
bit 6 - suggest binary search (unused) bit 6 - suggest binary search (unused)
bit 7 - 1 -> (internal) tree of anodes bit 7 - 1 -> (internal) tree of anodes
0 -> (leaf) list of extents */ 0 -> (leaf) list of extents */
u8 fill[3]; u8 fill[3];
u8 n_free_nodes; /* free nodes in following array */ u8 n_free_nodes; /* free nodes in following array */
u8 n_used_nodes; /* used nodes in following array */ u8 n_used_nodes; /* used nodes in following array */
__le16 first_free; /* offset from start of header to __le16 first_free; /* offset from start of header to
first free node in array */ first free node in array */
union { );
/* (internal) 2-word entries giving subtree pointers */ union {
DECLARE_FLEX_ARRAY(struct bplus_internal_node, internal); /* (internal) 2-word entries giving subtree pointers */
/* (external) 3-word entries giving sector runs */ DECLARE_FLEX_ARRAY(struct bplus_internal_node, internal);
DECLARE_FLEX_ARRAY(struct bplus_leaf_node, external); /* (external) 3-word entries giving sector runs */
} u; DECLARE_FLEX_ARRAY(struct bplus_leaf_node, external);
} u;
}; };
static_assert(offsetof(struct bplus_header, u.internal) == sizeof(struct bplus_header_fixed),
"struct member likely outside of struct_group_tagged()");
static inline bool bp_internal(struct bplus_header *bp) static inline bool bp_internal(struct bplus_header *bp)
{ {
@@ -453,7 +471,7 @@ struct fnode
__le16 flags; /* bit 1 set -> ea_secno is an anode */ __le16 flags; /* bit 1 set -> ea_secno is an anode */
/* bit 8 set -> directory. first & only extent /* bit 8 set -> directory. first & only extent
points to dnode. */ points to dnode. */
struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */ struct bplus_header_fixed btree; /* b+ tree, 8 extents or 12 subtrees */
union { union {
struct bplus_leaf_node external[8]; struct bplus_leaf_node external[8];
struct bplus_internal_node internal[12]; struct bplus_internal_node internal[12];
@@ -495,7 +513,7 @@ struct anode
__le32 self; /* pointer to this anode */ __le32 self; /* pointer to this anode */
__le32 up; /* parent anode or fnode */ __le32 up; /* parent anode or fnode */
struct bplus_header btree; /* b+tree, 40 extents or 60 subtrees */ struct bplus_header_fixed btree; /* b+tree, 40 extents or 60 subtrees */
union { union {
struct bplus_leaf_node external[40]; struct bplus_leaf_node external[40];
struct bplus_internal_node internal[60]; struct bplus_internal_node internal[60];

View File

@@ -178,14 +178,14 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea
} }
if (!fnode_is_dir(fnode)) { if (!fnode_is_dir(fnode)) {
if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
(bp_internal(&fnode->btree) ? 12 : 8)) { (bp_internal(GET_BTREE_PTR(&fnode->btree)) ? 12 : 8)) {
hpfs_error(s, hpfs_error(s,
"bad number of nodes in fnode %08lx", "bad number of nodes in fnode %08lx",
(unsigned long)ino); (unsigned long)ino);
goto bail; goto bail;
} }
if (le16_to_cpu(fnode->btree.first_free) != if (le16_to_cpu(fnode->btree.first_free) !=
8 + fnode->btree.n_used_nodes * (bp_internal(&fnode->btree) ? 8 : 12)) { 8 + fnode->btree.n_used_nodes * (bp_internal(GET_BTREE_PTR(&fnode->btree)) ? 8 : 12)) {
hpfs_error(s, hpfs_error(s,
"bad first_free pointer in fnode %08lx", "bad first_free pointer in fnode %08lx",
(unsigned long)ino); (unsigned long)ino);
@@ -233,12 +233,12 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buff
goto bail; goto bail;
} }
if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes != if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
(bp_internal(&anode->btree) ? 60 : 40)) { (bp_internal(GET_BTREE_PTR(&anode->btree)) ? 60 : 40)) {
hpfs_error(s, "bad number of nodes in anode %08x", ano); hpfs_error(s, "bad number of nodes in anode %08x", ano);
goto bail; goto bail;
} }
if (le16_to_cpu(anode->btree.first_free) != if (le16_to_cpu(anode->btree.first_free) !=
8 + anode->btree.n_used_nodes * (bp_internal(&anode->btree) ? 8 : 12)) { 8 + anode->btree.n_used_nodes * (bp_internal(GET_BTREE_PTR(&anode->btree)) ? 8 : 12)) {
hpfs_error(s, "bad first_free pointer in anode %08x", ano); hpfs_error(s, "bad first_free pointer in anode %08x", ano);
goto bail; goto bail;
} }

View File

@@ -52,8 +52,10 @@ static struct dentry *hpfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
dee.fnode = cpu_to_le32(fno); dee.fnode = cpu_to_le32(fno);
dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result) {
err = -ENOMEM;
goto bail2; goto bail2;
}
hpfs_init_inode(result); hpfs_init_inode(result);
result->i_ino = fno; result->i_ino = fno;
hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_parent_dir = dir->i_ino;
@@ -153,9 +155,10 @@ static int hpfs_create(struct mnt_idmap *idmap, struct inode *dir,
dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result) {
err = -ENOMEM;
goto bail1; goto bail1;
}
hpfs_init_inode(result); hpfs_init_inode(result);
result->i_ino = fno; result->i_ino = fno;
result->i_mode |= S_IFREG; result->i_mode |= S_IFREG;
@@ -239,9 +242,10 @@ static int hpfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result) {
err = -ENOMEM;
goto bail1; goto bail1;
}
hpfs_init_inode(result); hpfs_init_inode(result);
result->i_ino = fno; result->i_ino = fno;
hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_parent_dir = dir->i_ino;
@@ -314,8 +318,10 @@ static int hpfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result) {
err = -ENOMEM;
goto bail1; goto bail1;
}
result->i_ino = fno; result->i_ino = fno;
hpfs_init_inode(result); hpfs_init_inode(result);
hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_parent_dir = dir->i_ino;

View File

@@ -404,15 +404,11 @@ static int hpfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
break; break;
case Opt_timeshift: case Opt_timeshift:
{ {
int m = 1;
char *rhs = param->string; char *rhs = param->string;
int timeshift; int timeshift;
if (*rhs == '-') m = -1; if (kstrtoint(rhs, 0, &timeshift))
if (*rhs == '+' || *rhs == '-') rhs++; return -EINVAL;
timeshift = simple_strtoul(rhs, &rhs, 0) * m;
if (*rhs)
return -EINVAL;
ctx->timeshift = timeshift; ctx->timeshift = timeshift;
break; break;
} }