Skip to content

Commit 2ed81b4

Browse files
mjguzikbrauner
authored andcommitted
fs: make plain ->i_state access fail to compile
... to make sure all accesses are properly validated. Merely renaming the var to __i_state still lets the compiler make the following suggestion: error: 'struct inode' has no member named 'i_state'; did you mean '__i_state'? Unfortunately some people will add the __'s and call it a day. In order to make it harder to mess up in this way, hide it behind a struct. The resulting error message should be convincing in terms of checking what to do: error: invalid operands to binary & (have 'struct inode_state_flags' and 'int') Of course people determined to do a plain access can still do it, but nothing can be done for that case. Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 18c6139 commit 2ed81b4

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

include/linux/fs.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,13 @@ enum inode_state_flags_enum {
785785
#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
786786
#define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)
787787

788+
/*
789+
* Use inode_state_read() & friends to access.
790+
*/
791+
struct inode_state_flags {
792+
enum inode_state_flags_enum __state;
793+
};
794+
788795
/*
789796
* Keep mostly read-only and often accessed (especially for
790797
* the RCU path lookup and 'stat' data) fields at the beginning
@@ -843,7 +850,7 @@ struct inode {
843850
#endif
844851

845852
/* Misc */
846-
enum inode_state_flags_enum i_state;
853+
struct inode_state_flags i_state;
847854
/* 32-bit hole */
848855
struct rw_semaphore i_rwsem;
849856

@@ -909,19 +916,19 @@ struct inode {
909916
*/
910917
static inline enum inode_state_flags_enum inode_state_read_once(struct inode *inode)
911918
{
912-
return READ_ONCE(inode->i_state);
919+
return READ_ONCE(inode->i_state.__state);
913920
}
914921

915922
static inline enum inode_state_flags_enum inode_state_read(struct inode *inode)
916923
{
917924
lockdep_assert_held(&inode->i_lock);
918-
return inode->i_state;
925+
return inode->i_state.__state;
919926
}
920927

921928
static inline void inode_state_set_raw(struct inode *inode,
922929
enum inode_state_flags_enum flags)
923930
{
924-
WRITE_ONCE(inode->i_state, inode->i_state | flags);
931+
WRITE_ONCE(inode->i_state.__state, inode->i_state.__state | flags);
925932
}
926933

927934
static inline void inode_state_set(struct inode *inode,
@@ -934,7 +941,7 @@ static inline void inode_state_set(struct inode *inode,
934941
static inline void inode_state_clear_raw(struct inode *inode,
935942
enum inode_state_flags_enum flags)
936943
{
937-
WRITE_ONCE(inode->i_state, inode->i_state & ~flags);
944+
WRITE_ONCE(inode->i_state.__state, inode->i_state.__state & ~flags);
938945
}
939946

940947
static inline void inode_state_clear(struct inode *inode,
@@ -947,7 +954,7 @@ static inline void inode_state_clear(struct inode *inode,
947954
static inline void inode_state_assign_raw(struct inode *inode,
948955
enum inode_state_flags_enum flags)
949956
{
950-
WRITE_ONCE(inode->i_state, flags);
957+
WRITE_ONCE(inode->i_state.__state, flags);
951958
}
952959

953960
static inline void inode_state_assign(struct inode *inode,
@@ -962,7 +969,7 @@ static inline void inode_state_replace_raw(struct inode *inode,
962969
enum inode_state_flags_enum setflags)
963970
{
964971
enum inode_state_flags_enum flags;
965-
flags = inode->i_state;
972+
flags = inode->i_state.__state;
966973
flags &= ~clearflags;
967974
flags |= setflags;
968975
inode_state_assign_raw(inode, flags);

0 commit comments

Comments
 (0)