19
19
*/
20
20
package org .dcache .nfs .vfs ;
21
21
22
+ import java .nio .ByteBuffer ;
23
+ import java .nio .ByteOrder ;
22
24
import java .util .Arrays ;
23
25
24
- public class Inode extends FileHandle {
26
+ import com .google .common .io .BaseEncoding ;
27
+
28
+ /**
29
+ * NFS file handle on wire representation format v1.
30
+ *
31
+ * <pre>
32
+ * byte fh_version; // file handle format version number; version 1 description
33
+ * byte[3] fh_magic // 0xcaffee
34
+ * uint32 fh_generation; // server boot time or 0 for permanent handles
35
+ * uint32 export_index; // index into export table
36
+ * byte fh_type // 1 if pseudo fs
37
+ * byte fh_olen; // length of opaque data
38
+ * byte[] fh_opaque; // FS specific opaque data <= 114
39
+ * </pre>
40
+ */
41
+ public class Inode {
42
+ private final static int MIN_LEN = 14 ;
43
+ private final static int VERSION = 1 ;
44
+ private final static int MAGIC = 0xCAFFEE ;
45
+ private final static byte [] FH_V0_REG = new byte [] {0x30 , 0x3a };
46
+ private final static byte [] FH_V0_PFS = new byte [] {0x32 , 0x35 , 0x35 , 0x3a };
47
+
48
+ private final int version ;
49
+ private final int magic ;
50
+ private final int generation ;
51
+ private final int exportIdx ;
52
+ private final int type ;
53
+ private final byte [] fs_opaque ;
54
+
55
+ @ Deprecated (forRemoval = true )
56
+ public Inode (FileHandle fh ) {
57
+ this (fh .bytes ());
58
+ }
59
+
60
+ /**
61
+ * This constructor will become marked {@code protected} in a future version.
62
+ *
63
+ * @param generation The handle generation (e.g., server boot time), or {@code 0} for permanent handles
64
+ * @param exportIdx The index into the export table
65
+ * @param type 1=pseudo FS
66
+ * @param fs_opaque FS specific opaque data (maximum 114 bytes)
67
+ */
68
+ @ Deprecated
69
+ public Inode (int generation , int exportIdx , int type , byte [] fs_opaque ) {
70
+ this .version = VERSION ;
71
+ this .magic = MAGIC ;
72
+ this .generation = generation ;
73
+ this .exportIdx = exportIdx ;
74
+ this .type = type ;
75
+ this .fs_opaque = fs_opaque ;
76
+ }
77
+
25
78
/**
26
79
* This constructor will become marked {@code protected} in a future version.
27
80
*
28
81
* @param bytes The VFS-specific bytes.
29
82
*/
30
83
@ Deprecated
31
84
public Inode (byte [] bytes ) {
32
- super (bytes );
85
+ if (bytes .length < MIN_LEN ) {
86
+ throw new IllegalArgumentException ("too short" );
87
+ }
88
+
89
+ ByteBuffer b = ByteBuffer .wrap (bytes );
90
+ b .order (ByteOrder .BIG_ENDIAN );
91
+
92
+ int magic_version = b .getInt ();
93
+ int geussVersion = (magic_version & 0xFF000000 ) >>> 24 ;
94
+ if (geussVersion == VERSION ) {
95
+ version = geussVersion ;
96
+ magic = magic_version & 0x00FFFFFF ;
97
+ if (magic != MAGIC ) {
98
+ throw new IllegalArgumentException ("Bad magic number" );
99
+ }
100
+
101
+ generation = b .getInt ();
102
+ exportIdx = b .getInt ();
103
+ type = (int ) b .get ();
104
+ int olen = (int ) b .get ();
105
+ fs_opaque = new byte [olen ];
106
+ b .get (fs_opaque );
107
+
108
+ } else if (arrayEquals (bytes , FH_V0_REG , FH_V0_REG .length )
109
+ || arrayEquals (bytes , FH_V0_PFS , FH_V0_PFS .length )) {
110
+ magic = MAGIC ;
111
+ generation = 0 ;
112
+ type = bytes [1 ] == FH_V0_REG [1 ] ? 0 : 1 ;
113
+ if (type == 1 ) {
114
+ /*
115
+ * convert pseudo inode into real one: '255:' => '0:' NOTICE: the converted handle will present himself
116
+ * as version 1
117
+ */
118
+ version = 1 ;
119
+ exportIdx = 0 ;
120
+ fs_opaque = new byte [bytes .length - 2 ];
121
+ System .arraycopy (bytes , 2 , fs_opaque , 0 , fs_opaque .length );
122
+ fs_opaque [0 ] = 0x30 ;
123
+ } else {
124
+ version = 0 ;
125
+ exportIdx = -1 ;
126
+ fs_opaque = bytes ;
127
+ }
128
+ } else {
129
+ throw new IllegalArgumentException ("Unsupported version: " + geussVersion );
130
+ }
33
131
}
34
132
35
- @ Deprecated (forRemoval = true )
36
- public Inode (FileHandle fh ) {
37
- this (fh .bytes ());
133
+ public int getVersion () {
134
+ return version ;
135
+ }
136
+
137
+ public int getMagic () {
138
+ return magic ;
139
+ }
140
+
141
+ public int getGeneration () {
142
+ return generation ;
143
+ }
144
+
145
+ public int getExportIdx () {
146
+ return exportIdx ;
147
+ }
148
+
149
+ public int getType () {
150
+ return type ;
151
+ }
152
+
153
+ public byte [] getFsOpaque () {
154
+ return fs_opaque ;
38
155
}
39
156
40
- Inode (int generation , int exportIdx , int type , byte [] fs_opaque ) {
41
- super (generation , exportIdx , type , fs_opaque );
157
+ public byte [] bytes () {
158
+ int len = fs_opaque .length + MIN_LEN ;
159
+ byte [] bytes = new byte [len ];
160
+ ByteBuffer b = ByteBuffer .wrap (bytes );
161
+ b .order (ByteOrder .BIG_ENDIAN );
162
+
163
+ b .putInt (version << 24 | magic );
164
+ b .putInt (generation );
165
+ b .putInt (exportIdx );
166
+ b .put ((byte ) type );
167
+ b .put ((byte ) fs_opaque .length );
168
+ b .put (fs_opaque );
169
+ return bytes ;
42
170
}
43
171
44
- public static Inode forFileHandle (FileHandle fh ) {
45
- if (fh instanceof Inode ) {
46
- return ((Inode ) fh );
172
+ @ Override
173
+ public String toString () {
174
+ return BaseEncoding .base16 ().lowerCase ().encode (this .bytes ());
175
+ }
176
+
177
+ private static boolean arrayEquals (byte [] a1 , byte [] a2 , int len ) {
178
+ if (a1 .length < len || a2 .length < len )
179
+ return false ;
180
+ for (int i = 0 ; i < len ; i ++) {
181
+ if (a1 [i ] != a2 [i ]) {
182
+ return false ;
183
+ }
47
184
}
48
- return new Inode ( fh . bytes ()) ;
185
+ return true ;
49
186
}
50
187
51
188
public static Inode forNfsHandle (byte [] bytes ) {
52
189
return new Inode (bytes );
53
190
}
54
191
55
192
public static Inode forFile (byte [] bytes ) {
56
- return new FileHandle . FileHandleBuilder (). buildInode ( bytes );
193
+ return new Inode ( 0 , 0 , 0 , bytes );
57
194
}
58
195
59
196
public byte [] getFileId () {
@@ -74,7 +211,7 @@ public boolean equals(Object obj) {
74
211
if (obj == null ) {
75
212
return false ;
76
213
}
77
- if (getClass () != obj . getClass ( )) {
214
+ if (!( obj instanceof Inode )) {
78
215
return false ;
79
216
}
80
217
final Inode other = (Inode ) obj ;
0 commit comments