diff options
author | Neil Brown <neilb@suse.de> | 2007-03-19 11:41:21 +1100 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2007-03-19 11:41:21 +1100 |
commit | 323d1c4d69b65ab36d951aca8473ceb02171ab08 (patch) | |
tree | 3de3df486887f235253646e927def626eee822f8 /utils/mountd/cache.c | |
parent | 97ccd3d1b61f20cd681a82089e83c58f97438f1a (diff) | |
download | nfs-utils-323d1c4d69b65ab36d951aca8473ceb02171ab08.tar.gz nfs-utils-323d1c4d69b65ab36d951aca8473ceb02171ab08.tar.xz nfs-utils-323d1c4d69b65ab36d951aca8473ceb02171ab08.zip |
Allow exporting of a subfilesystem when 'crossmnt' is set.
If we are asked to export a filesystem which is not explicitly
exported, but an ancestor is exported as 'crossmnt', export the
filesystems with the same options as the ancestor.
This is the first step to making 'crossmnt' effectively export
a tree of filesystems.
Diffstat (limited to 'utils/mountd/cache.c')
-rw-r--r-- | utils/mountd/cache.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c index 5612a9e..734ddd8 100644 --- a/utils/mountd/cache.c +++ b/utils/mountd/cache.c @@ -52,7 +52,7 @@ enum nfsd_fsid { * Record is terminated with newline. * */ -int cache_export_ent(char *domain, struct exportent *exp); +int cache_export_ent(char *domain, struct exportent *exp, char *p); char *lbuf = NULL; @@ -408,7 +408,7 @@ void nfsd_fh(FILE *f) } if (found) - cache_export_ent(dom, found); + cache_export_ent(dom, found, found->e_path); qword_print(f, dom); qword_printint(f, fsidtype); @@ -466,7 +466,7 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex write_fsloc(f, exp, path); if (exp->e_uuid == NULL) { char u[16]; - if (get_uuid(exp->e_path, NULL, 16, u)) { + if (get_uuid(path, NULL, 16, u)) { qword_print(f, "uuid"); qword_printhex(f, u, 16); } @@ -598,7 +598,7 @@ int cache_process_req(fd_set *readfds) * % echo $domain $path $[now+30*60] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel */ -int cache_export_ent(char *domain, struct exportent *exp) +int cache_export_ent(char *domain, struct exportent *exp, char *path) { int err; FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w"); @@ -606,12 +606,52 @@ int cache_export_ent(char *domain, struct exportent *exp) return -1; err = dump_to_cache(f, domain, exp->e_path, exp); - fclose(f); mountlist_add(domain, exp->e_path); + + while ((exp->e_flags & NFSEXP_CROSSMOUNT) && path) { + /* really an 'if', but we can break out of + * a 'while' more easily */ + /* Look along 'path' for other filesystems + * and export them with the same options + */ + struct stat stb; + int l = strlen(exp->e_path); + int dev; + + if (strlen(path) <= l || path[l] != '/' || + strncmp(exp->e_path, path, l) != 0) + break; + if (stat(exp->e_path, &stb) != 0) + break; + dev = stb.st_dev; + while(path[l] == '/') { + char c; + int err; + + l++; + while (path[l] != '/' && path[l]) + l++; + c = path[l]; + path[l] = 0; + err = lstat(path, &stb); + path[l] = c; + if (err < 0) + break; + if (stb.st_dev == dev) + continue; + dev = stb.st_dev; + path[l] = 0; + dump_to_cache(f, domain, path, exp); + path[l] = c; + } + break; + } + + fclose(f); return err; } -int cache_export(nfs_export *exp) +int cache_export(nfs_export *exp, char *path) { int err; FILE *f; @@ -628,7 +668,7 @@ int cache_export(nfs_export *exp) fclose(f); - err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export) + err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export, path) || err; return err; } |