libnfs
libnfs copied to clipboard
unnecessary GETATTR call in nfs_mount()
I was following logic in nfs_mount() and noticed that in nfs3_mount_6_cb() instead of using object attributes (if they were returned by server) an additional GETATTR call is issued. What is even more confusing -- returned data is discarded in nfs3_mount_7_cb() and a series of additional GETATTR calls is issued for all nested exports (if present) -- results of these are actually saved in some structure.
@sahlberg Can you explain what's going on here -- why we make dummy GETATTR call for root and why we need attributes of nested exports?
... wrt nested mounts/exports: looks like the idea was to perform "auto-mounting" of nested exports (exported directories that are sub-directories wrt our root). But:
-
it looks like implementation is completely contained to nfs3 layer -- i.e.
rpc_nfs3_lookup_async()will ignore nested mounts (which makes sense, actually) -
nested mount attributes are extracted only once and with time inevitably will become stale/outdated
-
the only place where nested mount attributes are used is in
nfs3_opendir_cb()which is used to process results ofREADDIRPLUScall: we check if server returned attributes in related entry and if not -- make a lookup in nested mount list. If we found a nested mount with precisely same path -- we use it's (probably stale!) attributes. If not -- relatednfsdirentstructure is left to be populated later bylookup_missing_attributes(). I seems that we expect server to never provide attributes for nested exports -- this is incorrect (according to my reading of RFC 1813). Also, I've seen cases on Dell EMC Unity whenREADDIRPLUSdidn't returnname_handleand attributes for some seemingly random files -- standard allows server to do that if it encountered a problem retrieving data. -
... amazingly enough
name_handleisn't used at all -- this is probably main reason whyREADDIRPLUSwas introduced.
one more thought on nested mounts:
-
what if directory enumeration doesn't produce entry with same name as last component of nested mount. I.e. let's say we enumerate
/vol0/AAAand there is a nested mount/vol0/AAA/BBB, butBBBnever comes up in enumeration (because some other path was exported as/vol0/AAA/BBB) -- we will end up not observing files in nested mount at all -
and what if BBB was returned by enumeration, but it isn't a directory? Should we "substitute" it with root of
/vol0/AAA/BBBexport? It feels weird...