fs: add option to evaluate symlink or mtpt

Currently, several fs subcommands for Windows offer an option (-literal)
to evaluate symlink / mount point rather than the object it refers to.
Provide the same option on Unix for fs_getfid.

Change-Id: I55ab5f96d5b9e63efbe7e938647edba05a1787ed
Reviewed-on: https://gerrit.openafs.org/14542
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
Marcio Barbosa 2021-07-01 10:47:50 -03:00 committed by Benjamin Kaduk
parent a9c1939eeb
commit 83d947c150
5 changed files with 86 additions and 11 deletions

View File

@ -32,8 +32,8 @@ The path of the file (or directory).
=item B<-literal>
Windows only: for a symlink or mount point, evaluates the specified object
rather than the object it refers to.
For a symlink or mount point, evaluates the specified object rather than
the object it refers to.
=item B<-help>

View File

@ -315,6 +315,7 @@ DECL_PIOCTL(PGetPAG);
#if defined(AFS_CACHE_BYPASS) && defined(AFS_LINUX_ENV)
DECL_PIOCTL(PSetCachingThreshold);
#endif
DECL_PIOCTL(PGetLiteralFID);
/*
* A macro that says whether we're going to need HandleClientContext().
@ -431,6 +432,7 @@ static pioctlFunction CpioctlSw[] = {
PPrecache, /* 12 */
PGetPAG, /* 13 */
PFlushAllVolumeData, /* 14 */
PGetLiteralFID, /* 15 -- get FID from parent directory */
};
static pioctlFunction OpioctlSw[] = {
@ -5641,3 +5643,50 @@ DECL_PIOCTL(PNFSNukeCreds)
ReleaseWriteLock(&afs_xuser);
return 0;
}
/*!
* VIOC_GETLITERALFID (15) - Get FID from parent directory.
*
* Same as VIOCGETFID, but instead of getting the FID directly from the vcache,
* get this information by looking up the last component in the parent
* directory.
*
* \ingroup pioctl
*
* \param[in] ain last component in a path
* \param[out] aout 'struct VenusFid' for the FID associated with 'ain'
*
* \return 0 on success; errno otherwise.
*/
DECL_PIOCTL(PGetLiteralFID)
{
int code;
char *name;
struct VenusFid tfid;
struct sysname_info sysState;
AFS_STATCNT(PGetLiteralFID);
memset(&tfid, 0, sizeof(tfid));
memset(&sysState, 0, sizeof(sysState));
if (!avc || (afs_pd_getStringPtr(ain, &name) != 0)) {
code = EINVAL;
goto out;
}
/* get fid associated with name */
code = afs_LookupName(avc, areq, name, &sysState, &tfid);
if (code) {
goto out;
}
tfid.Cell = avc->f.fid.Cell;
tfid.Fid.Volume = avc->f.fid.Fid.Volume;
code = afs_pd_putBytes(aout, &tfid, sizeof(tfid));
out:
if (sysState.allocked) {
osi_FreeLargeSpace(sysState.name);
}
return code;
}

View File

@ -659,7 +659,8 @@ struct afs_MeanStats {
AFS_CS(PPrefetchFromTape) /* afs_pioctl.c */ \
AFS_CS(PFlushAllVolumeData) /* afs_pioctl.c */ \
AFS_CS(afs_InitVolSlot) /* afs_volume.c */ \
AFS_CS(afs_SetupVolSlot) /* afs_volume.c */
AFS_CS(afs_SetupVolSlot) /* afs_volume.c */ \
AFS_CS(PGetLiteralFID) /* afs_pioctl.c */
struct afs_CMCallStats {
#define AFS_CS(call) afs_int32 C_ ## call;

View File

@ -105,6 +105,7 @@
#define VIOCPRECACHE _CVICEIOCTL(12) /* precache size */
#define VIOC_GETPAG _CVICEIOCTL(13) /* get pag value */
#define VIOC_FLUSHALL _CVICEIOCTL(14) /* flush all volume data */
#define VIOC_GETLITERALFID _CVICEIOCTL(15) /* get fid from parent directory */
/* OpenAFS-specific 'O' pioctl's */
#define VIOC_NFS_NUKE_CREDS _OVICEIOCTL(1) /* nuke creds for all PAG's */

View File

@ -1724,7 +1724,7 @@ QuotaCmd(struct cmd_syndesc *as, void *arock)
static int
GetLastComponent(const char *data, char **outdir, char **outbase,
int *thru_symlink)
int *thru_symlink, int literal)
{
char orig_name[MAXPATHLEN]; /*Original name, may be modified */
char true_name[MAXPATHLEN]; /*``True'' dirname (e.g., symlink target) */
@ -1752,10 +1752,10 @@ GetLastComponent(const char *data, char **outdir, char **outbase,
}
/*
* The lstat succeeded. If the given file is a symlink, substitute
* the file name with the link name.
* The lstat succeeded. If the -literal flag wasn't specified and the given
* file is a symlink, substitute the file name with the link name.
*/
if ((statbuff.st_mode & S_IFMT) == S_IFLNK) {
if (!literal && (statbuff.st_mode & S_IFMT) == S_IFLNK) {
if (thru_symlink)
*thru_symlink = 1;
@ -1850,7 +1850,7 @@ ListMountCmd(struct cmd_syndesc *as, void *arock)
for (ti = as->parms[0].items; ti; ti = ti->next) {
if (GetLastComponent(ti->data, &parent_dir,
&last_component, &thru_symlink) != 0) {
&last_component, &thru_symlink, 0) != 0) {
error = 1;
continue;
}
@ -3946,6 +3946,8 @@ defect 3069
ts = cmd_CreateSyntax("getfid", GetFidCmd, NULL, 0,
"get fid for file(s)");
cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
cmd_AddParm(ts, "-literal", CMD_FLAG, CMD_OPTIONAL,
"literal evaluation of mountpoints and symlinks");
ts = cmd_CreateSyntax("discon", DisconCmd, NULL, 0,
"disconnection mode");
@ -4148,7 +4150,7 @@ FlushMountCmd(struct cmd_syndesc *as, void *arock)
for (ti = as->parms[0].items; ti; ti = ti->next) {
if (GetLastComponent(ti->data, &parent_dir,
&last_component, NULL) != 0) {
&last_component, NULL, 0) != 0) {
error = 1;
continue;
}
@ -4249,10 +4251,14 @@ GetFidCmd(struct cmd_syndesc *as, void *arock)
struct cmd_item *ti;
afs_int32 code;
int error = 0;
int error = 0, literal = 0;
char cell[MAXCELLCHARS];
SetDotDefault(&as->parms[0].items);
if (as->parms[1].items) {
/* -literal */
literal = 1;
}
for (ti = as->parms[0].items; ti; ti = ti->next) {
struct VenusFid vfid;
@ -4260,7 +4266,25 @@ GetFidCmd(struct cmd_syndesc *as, void *arock)
blob.out = (char *) &vfid;
blob.in_size = 0;
code = pioctl(ti->data, VIOCGETFID, &blob, 1);
if (literal) {
char *parent_dir = NULL;
char *last_component = NULL;
if (GetLastComponent(ti->data, &parent_dir,
&last_component, NULL, literal) != 0) {
error = 1;
continue;
}
blob.in = last_component;
blob.in_size = strlen(last_component) + 1;
code = pioctl(parent_dir, VIOC_GETLITERALFID, &blob, 1);
free(parent_dir);
free(last_component);
} else {
code = pioctl(ti->data, VIOCGETFID, &blob, 1);
}
if (code) {
Die(errno,ti->data);
error = 1;