Skip to content

Commit 3629b8f

Browse files
committed
core: Correct the Inode objects sent from PseudoFS to the underlying VFS
We currently store additional information such as "ExportId" and "PseudoInode" as parts of the Inode. VirtualFileSystems that store Inode as a whole (rather than only the "fileId" bit) may not recognize such objects, unless we remove this additional information. Related: #149 Signed-off-by: Christian Kohlschütter <[email protected]>
1 parent dd74e72 commit 3629b8f

File tree

1 file changed

+60
-34
lines changed

1 file changed

+60
-34
lines changed

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

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public int access(Subject subject, Inode inode, int mode) throws IOException {
109109
throw new InvalException("invalid access mask");
110110
}
111111

112-
Stat stat = _inner.getattr(inode);
112+
Stat stat = _inner.getattr(innerInode(inode));
113113
if ((mode & ACCESS4_READ) != 0) {
114114
if (canAccess(inode, stat, ACE4_READ_DATA)) {
115115
accessmask |= ACCESS4_READ;
@@ -170,7 +170,7 @@ public int access(Subject subject, Inode inode, int mode) throws IOException {
170170
}
171171
}
172172

173-
return accessmask & _inner.access(subject, inode, accessmask);
173+
return accessmask & _inner.access(subject, innerInode(inode), accessmask);
174174
}
175175

176176
@Override
@@ -181,12 +181,14 @@ public Inode create(Inode parent, Stat.Type type, String path, Subject subject,
181181
effectiveSubject = subject;
182182
}
183183

184+
Inode innerParent = innerInode(parent);
185+
184186
if (inheritUidGid(parent)) {
185-
Stat s = _inner.getattr(parent);
187+
Stat s = _inner.getattr(innerParent);
186188
effectiveSubject = toSubject(s.getUid(), s.getGid());
187189
}
188190

189-
return pushExportIndex(parent, _inner.create(parent, type, path, effectiveSubject, mode));
191+
return pushExportIndex(parent, _inner.create(innerParent, type, path, effectiveSubject, mode));
190192
}
191193

192194
@Override
@@ -220,18 +222,20 @@ public Inode lookup(Inode parent, String path) throws IOException {
220222
throw new NoEntException("the dcap magic file is blocked");
221223
}
222224

223-
return pushExportIndex(parent, _inner.lookup(parent, path));
225+
return pushExportIndex(parent, _inner.lookup(innerInode(parent), path));
224226
}
225227

226228
@Override
227229
public Inode link(Inode parent, Inode link, String path, Subject subject) throws IOException {
228230
checkAccess(link, ACE4_WRITE_ATTRIBUTES);
229231
Subject effectiveSubject = checkAccess(parent, ACE4_ADD_FILE);
232+
233+
Inode innerParent = innerInode(parent);
230234
if (inheritUidGid(parent)) {
231-
Stat s = _inner.getattr(parent);
235+
Stat s = _inner.getattr(innerParent);
232236
effectiveSubject = toSubject(s.getUid(), s.getGid());
233237
}
234-
return pushExportIndex(parent, _inner.link(parent, link, path, effectiveSubject));
238+
return pushExportIndex(parent, _inner.link(innerParent, link, path, effectiveSubject));
235239
}
236240

237241
@Override
@@ -240,7 +244,7 @@ public DirectoryStream list(Inode inode, byte[] verifier, long cookie) throws IO
240244
if (inode.isPseudoInode()) {
241245
return new DirectoryStream(listPseudoDirectory(inode)).tail(cookie);
242246
}
243-
DirectoryStream innerStrem = _inner.list(inode, verifier, cookie);
247+
DirectoryStream innerStrem = _inner.list(innerInode(inode), verifier, cookie);
244248
return innerStrem.transform(new PushParentIndex(inode));
245249
}
246250

@@ -251,24 +255,25 @@ public Inode mkdir(Inode parent, String path, Subject subject, int mode) throws
251255
effectiveSubject = subject;
252256
}
253257

258+
Inode innerParent = innerInode(parent);
254259
if (inheritUidGid(parent)) {
255-
Stat s = _inner.getattr(parent);
260+
Stat s = _inner.getattr(innerParent);
256261
effectiveSubject = toSubject(s.getUid(), s.getGid());
257262
}
258-
return pushExportIndex(parent, _inner.mkdir(parent, path, effectiveSubject, mode));
263+
return pushExportIndex(parent, _inner.mkdir(innerParent, path, effectiveSubject, mode));
259264
}
260265

261266
@Override
262267
public boolean move(Inode src, String oldName, Inode dest, String newName) throws IOException {
263268
checkAccess(src, ACE4_DELETE_CHILD);
264269
checkAccess(dest, ACE4_ADD_FILE | ACE4_DELETE_CHILD);
265-
return _inner.move(src, oldName, dest, newName);
270+
return _inner.move(innerInode(src), oldName, innerInode(dest), newName);
266271
}
267272

268273
@Override
269274
public Inode parentOf(Inode inode) throws IOException {
270275

271-
Inode parent = _inner.parentOf(inode);
276+
Inode parent = _inner.parentOf(innerInode(inode));
272277
Inode asPseudo = realToPseudo(parent);
273278
if (isPseudoDirectory(asPseudo)) {
274279
/*
@@ -283,64 +288,67 @@ public Inode parentOf(Inode inode) throws IOException {
283288
@Override
284289
public int read(Inode inode, byte[] data, long offset, int count) throws IOException {
285290
checkAccess(inode, ACE4_READ_DATA);
286-
return _inner.read(inode, data, offset, count);
291+
return _inner.read(innerInode(inode), data, offset, count);
287292
}
288293

289294
@Override
290295
public int read(Inode inode, ByteBuffer data, long offset) throws IOException {
291296
checkAccess(inode, ACE4_READ_DATA);
292-
return _inner.read(inode, data, offset);
297+
return _inner.read(innerInode(inode), data, offset);
293298
}
294299

295300
@Override
296301
public String readlink(Inode inode) throws IOException {
297302
checkAccess(inode, ACE4_READ_DATA);
298-
return _inner.readlink(inode);
303+
return _inner.readlink(innerInode(inode));
299304
}
300305

301306
@Override
302307
public void remove(Inode parent, String path) throws IOException {
308+
Inode innerParent = innerInode(parent);
303309
try {
304310
checkAccess(parent, ACE4_DELETE_CHILD);
305311
} catch (ChimeraNFSException e) {
306312
if (e.getStatus() == nfsstat.NFSERR_ACCESS) {
307-
Inode inode = pushExportIndex(parent, _inner.lookup(parent, path));
313+
Inode inode = pushExportIndex(parent, _inner.lookup(innerParent, path));
308314
checkAccess(inode, ACE4_DELETE);
309315
} else {
310316
throw e;
311317
}
312318
}
313-
_inner.remove(parent, path);
319+
_inner.remove(innerParent, path);
314320
}
315321

316322
@Override
317323
public Inode symlink(Inode parent, String path, String link, Subject subject, int mode) throws IOException {
324+
Inode innerParent = innerInode(parent);
325+
318326
Subject effectiveSubject = checkAccess(parent, ACE4_ADD_FILE);
319327
if (inheritUidGid(parent)) {
320-
Stat s = _inner.getattr(parent);
328+
Stat s = _inner.getattr(innerParent);
321329
effectiveSubject = toSubject(s.getUid(), s.getGid());
322330
}
323-
return pushExportIndex(parent, _inner.symlink(parent, path, link, effectiveSubject, mode));
331+
return pushExportIndex(parent, _inner.symlink(innerParent, path, link, effectiveSubject, mode));
324332
}
325333

326334
@Override
327335
public WriteResult write(Inode inode, byte[] data, long offset, int count, StabilityLevel stabilityLevel)
328336
throws IOException {
329337
checkAccess(inode, ACE4_WRITE_DATA);
330-
return _inner.write(inode, data, offset, count, stabilityLevel);
338+
return _inner.write(innerInode(inode), data, offset, count, stabilityLevel);
331339
}
332340

333341
@Override
334342
public WriteResult write(Inode inode, ByteBuffer data, long offset, StabilityLevel stabilityLevel)
335343
throws IOException {
336344
checkAccess(inode, ACE4_WRITE_DATA);
337-
return _inner.write(inode, data, offset, stabilityLevel);
345+
return _inner.write(innerInode(inode), data, offset, stabilityLevel);
338346
}
339347

340348
@Override
341349
public Stat getattr(Inode inode) throws IOException {
342350
checkAccess(inode, ACE4_READ_ATTRIBUTES);
343-
return _inner.getattr(inode);
351+
return _inner.getattr(innerInode(inode));
344352
}
345353

346354
@Override
@@ -368,51 +376,51 @@ public void setattr(Inode inode, Stat stat) throws IOException {
368376
}
369377

370378
checkAccess(inode, mask);
371-
_inner.setattr(inode, stat);
379+
_inner.setattr(innerInode(inode), stat);
372380
}
373381

374382
@Override
375383
public nfsace4[] getAcl(Inode inode) throws IOException {
376384
checkAccess(inode, ACE4_READ_ACL);
377-
return _inner.getAcl(inode);
385+
return _inner.getAcl(innerInode(inode));
378386
}
379387

380388
@Override
381389
public void setAcl(Inode inode, nfsace4[] acl) throws IOException {
382390
checkAccess(inode, ACE4_WRITE_ACL);
383-
_inner.setAcl(inode, acl);
391+
_inner.setAcl(innerInode(inode), acl);
384392
}
385393

386394
@Override
387395
public byte[] getXattr(Inode inode, String attr) throws IOException {
388396
checkAccess(inode, ACE4_READ_DATA);
389-
return _inner.getXattr(inode, attr);
397+
return _inner.getXattr(innerInode(inode), attr);
390398
}
391399

392400
@Override
393401
public void setXattr(Inode inode, String attr, byte[] value, SetXattrMode mode) throws IOException {
394402
checkAccess(inode, ACE4_WRITE_DATA);
395-
_inner.setXattr(inode, attr, value, mode);
403+
_inner.setXattr(innerInode(inode), attr, value, mode);
396404
}
397405

398406
@Override
399407
public String[] listXattrs(Inode inode) throws IOException {
400408
checkAccess(inode, ACE4_READ_DATA);
401-
return _inner.listXattrs(inode);
409+
return _inner.listXattrs(innerInode(inode));
402410
}
403411

404412
@Override
405413
public void removeXattr(Inode inode, String attr) throws IOException {
406414
checkAccess(inode, ACE4_WRITE_DATA);
407-
_inner.removeXattr(inode, attr);
415+
_inner.removeXattr(innerInode(inode), attr);
408416
}
409417

410418
private Subject checkAccess(Inode inode, int requestedMask) throws IOException {
411419
return checkAccess(inode, requestedMask, true);
412420
}
413421

414422
private Subject checkAccess(Inode inode, int requestedMask, boolean shouldLog) throws IOException {
415-
return checkAccess(inode, _inner.getattr(inode), requestedMask, shouldLog);
423+
return checkAccess(inode, _inner.getattr(innerInode(inode)), requestedMask, shouldLog);
416424
}
417425

418426
private Subject checkAccess(Inode inode, Stat stat, int requestedMask, boolean shouldLog) throws IOException {
@@ -467,7 +475,7 @@ private Subject checkAccess(Inode inode, Stat stat, int requestedMask, boolean s
467475
}
468476

469477
if (export.checkAcls()) {
470-
aclMatched = _inner.getAclCheckable().checkAcl(_subject, inode, requestedMask);
478+
aclMatched = _inner.getAclCheckable().checkAcl(_subject, innerInode(inode), requestedMask);
471479
if (aclMatched == Access.DENY) {
472480
if (shouldLog) {
473481
_log.warn("Access deny: {} {} {}", _inetAddress, acemask4.toString(requestedMask),
@@ -586,14 +594,15 @@ private Collection<DirectoryEntry> listPseudoDirectory(Inode parent) throws Chim
586594
for (PseudoFsNode node : nodes) {
587595
if (node.id().equals(parent)) {
588596
if (node.isMountPoint()) {
589-
return newArrayList(_inner.list(parent, null, 0L).transform(new ConvertToRealInode(node)));
597+
return newArrayList(_inner.list(innerInode(parent), null, 0L).transform(new ConvertToRealInode(
598+
node)));
590599
} else {
591600
long cookie = 3; // artificial cookie. Values 0, 1 and 2 are reserved.
592601
List<DirectoryEntry> pseudoLs = new ArrayList<>();
593602
for (String s : node.getChildren()) {
594603
PseudoFsNode subNode = node.getChild(s);
595604
Inode inode = subNode.id();
596-
Stat stat = _inner.getattr(inode);
605+
Stat stat = _inner.getattr(innerInode(inode));
597606
DirectoryEntry e = new DirectoryEntry(s,
598607
subNode.isMountPoint()
599608
? pseudoIdToReal(inode, getIndexId(subNode)) : inode, stat, cookie);
@@ -653,7 +662,7 @@ private void pathToPseudoFs(final PseudoFsNode root, Set<PseudoFsNode> all, FsEx
653662
try {
654663
PseudoFsNode node = parent.getChild(s);
655664
if (node == null) {
656-
node = new PseudoFsNode(realToPseudo(_inner.lookup(parent.id(), s)));
665+
node = new PseudoFsNode(realToPseudo(_inner.lookup(innerInode(parent.id()), s)));
657666
parent.addChild(s, node);
658667
pathNodes.add(node);
659668
}
@@ -724,4 +733,21 @@ private static void checkSecurityFlavor(RpcAuth auth, FsExport.Sec minFlavor) th
724733
private boolean inheritUidGid(Inode inode) {
725734
return _exportTable.getExport(inode.exportIndex(), _inetAddress.getAddress()).isAllRoot();
726735
}
736+
737+
/**
738+
* Convert an {@link Inode} that is used by {@link PseudoFs} to an {@link Inode} that is understood
739+
* by the underlying file system.
740+
* <p>
741+
* We currently store additional information such as "ExportId" and "PseudoInode" as parts of the Inode.
742+
* {@link VirtualFileSystem}s that store {@link Inode} as a whole (rather than only the "fileId" bit)
743+
* may not recognize such objects, unless we remove this additional information.
744+
* <p>
745+
* Once {@link PseudoFs} handles this configuration internally, we can remove this conversion step.
746+
*
747+
* @param inode The {@link Inode} as passed from and to the NFS client.
748+
* @return The {@link Inode} as passed from {@link PseudoFs} to the underlying {@link VirtualFileSystem}.
749+
*/
750+
private Inode innerInode(Inode inode) {
751+
return Inode.forFile(inode.getFileId());
752+
}
727753
}

0 commit comments

Comments
 (0)