4 # srcdiff is used to compare current user level code with the current
5 # kernel code and advise of any differences between files which are
6 # sharing some or all of their content.
8 # There are two classes of sharing which we will check - header files
9 # in the include directory, which must be exactly the same (use diff)
10 # and source files which contain routines which must be exactly the
11 # same (but the userland file is always a subset of the kernel file,
12 # and hence a more flexible mechanism to "diff" is required).
14 # NB: to cross check that srcdiff is finding all the functions in the
15 # user source file, providing you have "mkproto" installed, you
16 # can "cd cmd/xfs/libxfs" and cut&paste this into a bourne shell:
17 # $ for file in xfs_*.c; do
18 # > mkproto -nps < $file | perl -ne '
19 # > END { print " $count\t- " }
20 # > s/^.* (xfs\w+|\*xfs\w+|xlog\w+|\*xlog\w+) \(.*/\1/ && { $count++ }'
23 # (compare this to "srcdiff | fgrep Total:") ... repeat for logprint.
26 die "WORKAREA not set" unless defined $ENV{'WORKAREA'};
27 chdir $ENV{'WORKAREA'};
28 my $xdiff = $ENV{'XDIFF'};
36 print STDERR "Illegal option $_\n";
42 print STDERR "Usage: $0 [-q]\n";
47 xfs_ag.h xfs_alloc.h xfs_alloc_btree.h xfs_arch.h
48 xfs_attr_leaf.h xfs_attr_sf.h xfs_bit.h xfs_bmap.h
49 xfs_bmap_btree.h xfs_btree.h xfs_buf_item.h
50 xfs_da_btree.h xfs_dfrag.h xfs_dinode.h xfs_dir.h
51 xfs_dir2.h xfs_dir2_block.h xfs_dir2_data.h
52 xfs_dir2_leaf.h xfs_dir2_node.h xfs_dir2_sf.h
53 xfs_dir_leaf.h xfs_dir_sf.h xfs_dqblk.h xfs_dquot_item.h
54 xfs_extfree_item.h xfs_ialloc.h xfs_imap.h
55 xfs_ialloc_btree.h xfs_inode.h xfs_inode_item.h
56 xfs_inum.h xfs_log.h xfs_log_priv.h xfs_log_recover.h
57 xfs_mount.h xfs_quota.h xfs_rtalloc.h
58 xfs_sb.h xfs_trans.h xfs_trans_space.h xfs_types.h
62 my ( $file, $prefix1, $prefix2 ) = @_;
64 `diff $prefix1/$file $prefix2/$file >/dev/null 2>&1`;
66 print sprintf("\t%-35s ... ", $file);
67 if ($? != 0) { print "FAILED\n"; }
68 else { print "ok\n"; }
70 printf("\t%-35s ... ", $file);
75 print "\n=== Checking headers ===\n";
77 straightdiff $_, 'cmd/xfs/include', 'linux/fs/xfs';
79 straightdiff 'xfs_cred.h', 'cmd/xfs/include', 'linux/fs/xfs/linux';
80 straightdiff 'xfs_fs.h', 'cmd/xfs/include', 'linux/include/linux';
81 straightdiff 'attributes.h', 'cmd/xfs/include', 'linux/include/linux';
82 straightdiff 'acl.h', 'cmd/acl/include', 'linux/include/linux';
83 straightdiff 'arch.h', 'cmd/xfs/include', 'linux/fs/xfs/support';
84 straightdiff 'xqm.h', 'cmd/xfs/include', 'linux/include/linux';
88 # Implements a tri-state FSA, see comments for state transitions
89 # (knows about the way the XFS kernel code is written, & makes
90 # some assumptions so as to not need to parse generic C code).
91 # Accepts one line at a time from a source file, picking out the
92 # function bodies so they can be subsequently compared.
95 my $line; # line number in current source file
96 my $state; # current FSA state
97 my $funcbody; # current function body (contents)
100 my ( $newline ) = @_;
104 # if line looks like start of a function, transition to 1
105 # & squirrel line away as line 1 of current function
107 if ($newline =~ m/^[xfs|xlog]/) {
109 $funcbody = $newline;
114 # if line looks like start of a function, stay here
115 # & squirrel line away as line 1 of current function
116 # otherwise if line isn't start of function body,
117 # squirrel line away as next line of current function
118 # (args/..., but not sure this is a real function yet)
119 # otherwise (start of function)
120 # squirrel line away as next line of current function
121 # transition to state 2
122 elsif ($state == 1) {
123 if ($newline =~ m/^[xfs|xlog]/) {
124 $funcbody = $newline;
126 elsif ($newline =~ m/^\{/) {
128 $funcbody .= $newline;
133 # if line looks like end of function body,
134 # squirrel line away as last line of current function
135 # tell someone we have a complete function ready
136 # transition to state 0
138 # squirrel line away as next line of current function
139 elsif ($state == 2) {
140 $funcbody .= $newline;
141 if ($newline =~ m/^\}/) {
148 die "unknown state transition";
150 return undef; # i.e. not at end of a function
160 open(USER, "$file") || die "cannot open $file";
162 my $func = setstate($_);
163 push @funcs, $func if (defined($func)); # store function away
176 open(KERN, "$file") || die "cannot open $file";
178 my $func = setstate($_);
179 if (defined($func)) {
180 $func =~ m/^([xfs|xlog]\w+)\s*\(/;
181 next unless defined($1);
183 if (defined($func)) {
184 $funcs{$name} = $func; # store function away
193 my ( $sa, $sb ) = @_;
195 return unless defined($xdiff);
197 open(FILEA, "> /tmp/diff.user.$$") || die "cannot write to /tmp/diff.user.$$";
198 open(FILEB, "> /tmp/diff.kern.$$") || die "cannot write to /tmp/diff.kern.$$";
203 `$xdiff /tmp/diff.user.$$ /tmp/diff.kern.$$`;
204 unlink ("/tmp/diff.user.$$","/tmp/diff.kern.$$");
208 my ( $file, $prefix1, $prefix2 ) = @_;
214 print "\n=== Checking $file routines ===\n" unless ($quiet);
216 # iterate over user funcs, match up to kernel funcs
218 my @user = listfuncs "$prefix1/$file";
219 my %kern = hashfuncs "$prefix2/$file";
221 foreach my $userfunc (@user) {
223 $userfunc =~ m/^([xfs|xlog]\w+)\s*\(/;
224 next unless (defined($1));
228 if (exists($kern{$name})) {
229 if ($userfunc ne $kern{$name}) {
230 print "\n=== $file routines ===\n"
231 if (!$found++ && $quiet);
233 printf("\t%-35s ... ", $name);
235 diffme $userfunc, $kern{$name};
238 printf("\t%-35s ... ", $name);
243 print "Cannot find kernel function $userfunc";
244 print " in file $prefix2/$file\n";
247 ($count != 1) && ( $plural = 's' );
248 print "( Total: $count routine$plural checked in $file )\n" unless ($quiet);
251 # cmd/xfs/{libxfs,logprint}/* fs/xfs/*
253 xfs_alloc.c xfs_alloc_btree.c xfs_attr_leaf.c xfs_bit.c
254 xfs_bmap.c xfs_bmap_btree.c xfs_btree.c xfs_da_btree.c
255 xfs_dir.c xfs_dir2.c xfs_dir2_block.c xfs_dir2_data.c
256 xfs_dir2_leaf.c xfs_dir2_node.c xfs_dir2_sf.c
257 xfs_dir_leaf.c xfs_ialloc.c xfs_ialloc_btree.c
258 xfs_inode.c xfs_rtalloc.c xfs_rtbit.c xfs_mount.c
262 print "\n=== Checking libxfs code ===\n";
263 foreach (@funclist) {
264 functiondiff $_, 'cmd/xfs/libxfs', 'linux/fs/xfs';
266 print "\n=== Checking logprint code ===\n";
267 functiondiff 'xfs_log_recover.c', 'cmd/xfs/logprint', 'linux/fs/xfs';