Skip to content

Commit ce77a51

Browse files
committed
core: Make FileHandle a subclass of Inode; deprecate FileHandle
In an effort to simplify file handle/inode usage, move all required FileHandle logic into Inode, and deprecate FileHandle for future use. Move FileHandleBuilder usage to an Inode constructor for now. Adjust test code wherever necessary. Related: #149 Signed-off-by: Christian Kohlschütter <[email protected]>
1 parent 96d8786 commit ce77a51

File tree

9 files changed

+180
-194
lines changed

9 files changed

+180
-194
lines changed

core/src/main/java/org/dcache/nfs/vfs/FileHandle.java

Lines changed: 6 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -16,156 +16,20 @@
1616
*/
1717
package org.dcache.nfs.vfs;
1818

19-
import java.nio.ByteBuffer;
20-
import java.nio.ByteOrder;
21-
22-
import com.google.common.io.BaseEncoding;
23-
24-
/**
25-
* NFS file handle on wire representation format v1.
26-
*
27-
* <pre>
28-
* byte fh_version; // file handle format version number; version 1 description
29-
* byte[3] fh_magic // 0xcaffee
30-
* uint32 fh_generation; // server boot time or 0 for permanent handles
31-
* uint32 export_index; // index into export table
32-
* byte fh_type // 1 if pseudo fs
33-
* byte fh_olen; // length of opaque data
34-
* byte[] fh_opaque; // FS specific opaque data <= 114
35-
* </pre>
36-
*/
37-
public class FileHandle {
38-
39-
private final static int MIN_LEN = 14;
40-
private final static int VERSION = 1;
41-
private final static int MAGIC = 0xCAFFEE;
19+
@Deprecated(forRemoval = true)
20+
public class FileHandle extends Inode {
4221
private final static byte[] EMPTY_FH = new byte[0];
43-
private final static byte[] FH_V0_REG = new byte[] {0x30, 0x3a};
44-
private final static byte[] FH_V0_PFS = new byte[] {0x32, 0x35, 0x35, 0x3a};
45-
46-
private final int version;
47-
private final int magic;
48-
private final int generation;
49-
private final int exportIdx;
50-
private final int type;
51-
private final byte[] fs_opaque;
52-
53-
public FileHandle(int generation, int exportIdx, int type, byte[] fs_opaque) {
54-
this.version = VERSION;
55-
this.magic = MAGIC;
56-
this.generation = generation;
57-
this.exportIdx = exportIdx;
58-
this.type = type;
59-
this.fs_opaque = fs_opaque;
60-
}
6122

6223
public FileHandle(byte[] bytes) {
63-
if (bytes.length < MIN_LEN) {
64-
throw new IllegalArgumentException("too short");
65-
}
66-
67-
ByteBuffer b = ByteBuffer.wrap(bytes);
68-
b.order(ByteOrder.BIG_ENDIAN);
69-
70-
int magic_version = b.getInt();
71-
int geussVersion = (magic_version & 0xFF000000) >>> 24;
72-
if (geussVersion == VERSION) {
73-
version = geussVersion;
74-
magic = magic_version & 0x00FFFFFF;
75-
if (magic != MAGIC) {
76-
throw new IllegalArgumentException("Bad magic number");
77-
}
78-
79-
generation = b.getInt();
80-
exportIdx = b.getInt();
81-
type = (int) b.get();
82-
int olen = (int) b.get();
83-
fs_opaque = new byte[olen];
84-
b.get(fs_opaque);
85-
86-
} else if (arrayEquals(bytes, FH_V0_REG, FH_V0_REG.length)
87-
|| arrayEquals(bytes, FH_V0_PFS, FH_V0_PFS.length)) {
88-
magic = MAGIC;
89-
generation = 0;
90-
type = bytes[1] == FH_V0_REG[1] ? 0 : 1;
91-
if (type == 1) {
92-
/*
93-
* convert pseudo inode into real one: '255:' => '0:' NOTICE: the converted handle will present himself
94-
* as version 1
95-
*/
96-
version = 1;
97-
exportIdx = 0;
98-
fs_opaque = new byte[bytes.length - 2];
99-
System.arraycopy(bytes, 2, fs_opaque, 0, fs_opaque.length);
100-
fs_opaque[0] = 0x30;
101-
} else {
102-
version = 0;
103-
exportIdx = -1;
104-
fs_opaque = bytes;
105-
}
106-
} else {
107-
throw new IllegalArgumentException("Unsupported version: " + geussVersion);
108-
}
109-
}
110-
111-
public int getVersion() {
112-
return version;
113-
}
114-
115-
public int getMagic() {
116-
return magic;
117-
}
118-
119-
public int getGeneration() {
120-
return generation;
121-
}
122-
123-
public int getExportIdx() {
124-
return exportIdx;
125-
}
126-
127-
public int getType() {
128-
return type;
129-
}
130-
131-
public byte[] getFsOpaque() {
132-
return fs_opaque;
24+
super(bytes);
13325
}
13426

135-
public byte[] bytes() {
136-
int len = fs_opaque.length + MIN_LEN;
137-
byte[] bytes = new byte[len];
138-
ByteBuffer b = ByteBuffer.wrap(bytes);
139-
b.order(ByteOrder.BIG_ENDIAN);
140-
141-
b.putInt(version << 24 | magic);
142-
b.putInt(generation);
143-
b.putInt(exportIdx);
144-
b.put((byte) type);
145-
b.put((byte) fs_opaque.length);
146-
b.put(fs_opaque);
147-
return bytes;
148-
}
149-
150-
@Override
151-
public String toString() {
152-
return BaseEncoding.base16().lowerCase().encode(this.bytes());
153-
}
154-
155-
private static boolean arrayEquals(byte[] a1, byte[] a2, int len) {
156-
if (a1.length < len || a2.length < len)
157-
return false;
158-
for (int i = 0; i < len; i++) {
159-
if (a1[i] != a2[i]) {
160-
return false;
161-
}
162-
}
163-
return true;
27+
public FileHandle(int generation, int exportIdx, int type, byte[] fs_opaque) {
28+
super(generation, exportIdx, type, fs_opaque);
16429
}
16530

31+
@Deprecated(forRemoval = true)
16632
public static class FileHandleBuilder {
167-
private int version = VERSION;
168-
private int magic = MAGIC;
16933
private int generation = 0;
17034
private int export_idx = 0;
17135
private int type = 0;
@@ -191,20 +55,10 @@ public FileHandleBuilder setFsOpaque(byte[] fs_opaque) {
19155
return this;
19256
}
19357

194-
/**
195-
* A shortcut with defaults
196-
*
197-
* @param opaque
198-
* @return
199-
*/
20058
public FileHandle build(byte[] opaque) {
20159
return new FileHandle(generation, export_idx, type, opaque);
20260
}
20361

204-
public Inode buildInode(byte[] opaque) {
205-
return new Inode(generation, export_idx, type, opaque);
206-
}
207-
20862
public FileHandle build() {
20963
return build(fs_opaque);
21064
}

core/src/main/java/org/dcache/nfs/vfs/Inode.java

Lines changed: 150 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,178 @@
1919
*/
2020
package org.dcache.nfs.vfs;
2121

22+
import java.nio.ByteBuffer;
23+
import java.nio.ByteOrder;
2224
import java.util.Arrays;
2325

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+
2578
/**
2679
* This constructor will become marked {@code protected} in a future version.
2780
*
2881
* @param bytes The VFS-specific bytes.
2982
*/
3083
@Deprecated
3184
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+
}
33131
}
34132

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;
38155
}
39156

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;
42170
}
43171

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+
}
47184
}
48-
return new Inode(fh.bytes());
185+
return true;
49186
}
50187

51188
public static Inode forNfsHandle(byte[] bytes) {
52189
return new Inode(bytes);
53190
}
54191

55192
public static Inode forFile(byte[] bytes) {
56-
return new FileHandle.FileHandleBuilder().buildInode(bytes);
193+
return new Inode(0, 0, 0, bytes);
57194
}
58195

59196
public byte[] getFileId() {
@@ -74,7 +211,7 @@ public boolean equals(Object obj) {
74211
if (obj == null) {
75212
return false;
76213
}
77-
if (getClass() != obj.getClass()) {
214+
if (!(obj instanceof Inode)) {
78215
return false;
79216
}
80217
final Inode other = (Inode) obj;

0 commit comments

Comments
 (0)