@@ -72,6 +72,18 @@ def fsnotify_group_for_each_mark(group: Object) -> Iterator[Object]:
7272 )
7373
7474
75+ def _get_object_no_type (obj : Object ) -> Tuple [str , Object ]:
76+ # obj may be:
77+ # - struct fsnotify_mark_connector (if it exists)
78+ # - struct fsnotify_mark (if this kernel version has no connector struct)
79+ if obj .flags & 0x1 :
80+ return "inode" , obj .inode
81+ elif obj .flags & 0x2 :
82+ return "vfsmount" , obj .vfsmount
83+ else :
84+ return "unknown" , NULL (obj .prog_ , "void *" )
85+
86+
7587def fsnotify_mark_object (mark : Object ) -> Tuple [str , Object ]:
7688 """
7789 For an fsnotify mark, determine what kind of object and return it
@@ -81,41 +93,47 @@ def fsnotify_mark_object(mark: Object) -> Tuple[str, Object]:
8193 pointer to the object. If we don't understand the object type, then we
8294 return ("unknown", NULL).
8395
84- :param mark: ``struct fsnotify-mark *``
96+ :param mark: ``struct fsnotify_mark *``
8597 :returns: (object type, object pointer)
8698 """
87- conn = mark .connector
8899 prog = mark .prog_
89100
90- if not hasattr (conn , "type" ):
101+ try :
102+ conn = mark .connector
103+ except AttributeError :
104+ # Commit 9dd813c15b2c1 ("fsnotify: Move mark list head from object into
105+ # dedicated structure") is the beginning of a series that introduces the
106+ # fsnotify_mark_connector. Prior to this, the mark directly pointed at
107+ # the object it contained. This was merged in 4.12.
108+ return _get_object_no_type (mark )
109+
110+ try :
111+ type_ = conn .type .read_ ()
112+ except AttributeError :
91113 # Commit d6f7b98bc8147 ("fsnotify: use type id to identify connector
92114 # object type") adds a type field to the connector. Before this, type
93115 # was expressed as bits in the flag field. The bit numbers were
94116 # preprocessor definitions, let's just hardcode them here.
95- if conn .flags & 0x1 :
96- return "inode" , conn .inode
97- elif conn .flags & 0x2 :
98- return "vfsmount" , conn .vfsmount
99- else :
100- return "unknown" , NULL (prog , "void *" )
117+ return _get_object_no_type (conn )
118+
101119 # See fsnotify_conn_{inode,mount,sb} in fs/notify/fsnotify.h
102- if conn . type == prog .constant ("FSNOTIFY_OBJ_TYPE_INODE" ):
120+ if type_ == prog .constant ("FSNOTIFY_OBJ_TYPE_INODE" ):
103121 # Prior to 36f10f55ff1d2 ("fsnotify: let connector point to an abstract
104122 # object"), there were direct pointers in the connector.
105123 if hasattr (conn , "inode" ):
106124 return "inode" , conn .inode
107125 return "inode" , container_of (
108126 conn .obj , "struct inode" , "i_fsnotify_marks"
109127 )
110- elif conn . type == prog .constant ("FSNOTIFY_OBJ_TYPE_VFSMOUNT" ):
128+ elif type_ == prog .constant ("FSNOTIFY_OBJ_TYPE_VFSMOUNT" ):
111129 # Prior to 36f10f55ff1d2 ("fsnotify: let connector point to an abstract
112130 # object"), there were direct pointers in the connector.
113131 if hasattr (conn , "vfsmount" ):
114132 return "vfsmount" , conn .vfsmount
115133 return "vfsmount" , container_of (
116134 conn .obj , "struct mount" , "mnt_fsnotify_marks"
117135 )
118- elif conn . type == prog .constant ("FSNOTIFY_OBJ_TYPE_SB" ):
136+ elif type_ == prog .constant ("FSNOTIFY_OBJ_TYPE_SB" ):
119137 # The "sb" object type was not present when 36f10f55ff1d2 ("fsnotify:
120138 # let connector point to an abstract object") so it will never have an
121139 # "sb" field.
0 commit comments