struct libmnt_optlist *ol;
struct mount_attr attr = { .attr_clr = 0 };
unsigned int callflags = AT_EMPTY_PATH;
- uint64_t mask = 0;
+ uint64_t set = 0, clr = 0;
int rc;
api = get_sysapi(cxt, hs);
if (!ol)
return -ENOMEM;
- rc = mnt_optlist_get_attrs(ol, &mask);
+ rc = mnt_optlist_get_attrs(ol, &set, &clr);
if (rc)
return rc;
if (mnt_optlist_is_recursive(ol))
callflags |= AT_RECURSIVE;
- DBG(HOOK, ul_debugobj(hs, "mount_setattr(set=0x%" PRIx64")", mask));
- attr.attr_set = mask;
+ DBG(HOOK, ul_debugobj(hs,
+ "mount_setattr(set=0x%08" PRIx64" clr=0x%08" PRIx64")", set, clr));
+ attr.attr_set = set;
+ attr.attr_clr = clr;
rc = mount_setattr(api->fd_tree, "", callflags, &attr, sizeof(attr));
set_syscall_status(cxt, "move_setattr", rc == 0);
{
struct libmnt_optlist *ol;
unsigned long flags = 0;
- uint64_t attrs = 0;
+ uint64_t set = 0, clr = 0;
int rc = 0;
assert(cxt);
/* MOUNT_ATTR_* flags for mount_setattr() */
if (!rc)
- rc = mnt_optlist_get_attrs(ol, &attrs);
+ rc = mnt_optlist_get_attrs(ol, &set, &clr);
/* open_tree() or fsopen() */
if (!rc)
hook_reconfigure_mount);
/* call mount_setattr() */
- if (!rc && attrs != 0)
+ if (!rc && (set != 0 || clr != 0))
rc = mnt_context_append_hook(cxt, hs, MNT_STAGE_MOUNT, NULL,
hook_set_vfsflags);
extern int mnt_optlist_get_flags(struct libmnt_optlist *ls, unsigned long *flags,
const struct libmnt_optmap *map, unsigned int what);
-extern int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *attrs);
+extern int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *set, uint64_t *clr);
extern int mnt_optlist_get_optstr(struct libmnt_optlist *ol, const char **optstr,
const struct libmnt_optmap *map, unsigned int what);
extern int mnt_optlist_strdup_optstr(struct libmnt_optlist *ls, char **optstr,
return 0;
}
-/*
- * Like mnt_optlist_get_flags() for VFS flags, but converts classic MS_* flags to
- * new MOUNT_ATTR_*
- */
-int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *attrs)
-{
#ifdef UL_HAVE_MOUNT_API
- int rc;
- unsigned long flags = 0;
-
- assert(ls);
- assert(ls->linux_map);
-
- rc = mnt_optlist_get_flags(ls, &flags, ls->linux_map, 0);
- if (rc)
- return rc;
+static inline uint64_t flags_to_attrs(unsigned long flags)
+{
+ uint64_t attrs = 0;
if (flags & MS_RDONLY)
- *attrs |= MOUNT_ATTR_RDONLY;
+ attrs |= MOUNT_ATTR_RDONLY;
if (flags & MS_NOSUID)
- *attrs |= MOUNT_ATTR_NOSUID;
+ attrs |= MOUNT_ATTR_NOSUID;
if (flags & MS_NOEXEC)
- *attrs |= MOUNT_ATTR_NOEXEC;
+ attrs |= MOUNT_ATTR_NOEXEC;
if (flags & MS_NODIRATIME)
- *attrs |= MOUNT_ATTR_NODIRATIME;
+ attrs |= MOUNT_ATTR_NODIRATIME;
if (flags & MS_RELATIME)
- *attrs |= MOUNT_ATTR_RELATIME;
+ attrs |= MOUNT_ATTR_RELATIME;
if (flags & MS_NOATIME)
- *attrs |= MOUNT_ATTR_NOATIME;
+ attrs |= MOUNT_ATTR_NOATIME;
if (flags & MS_STRICTATIME)
- *attrs |= MOUNT_ATTR_STRICTATIME;
+ attrs |= MOUNT_ATTR_STRICTATIME;
if (flags & MS_NOSYMFOLLOW)
- *attrs |= MOUNT_ATTR_NOSYMFOLLOW;
+ attrs |= MOUNT_ATTR_NOSYMFOLLOW;
+
+ return attrs;
+}
+#endif
+
+/*
+ * Like mnt_optlist_get_flags() for VFS flags, but converts classic MS_* flags to
+ * new MOUNT_ATTR_*
+ */
+int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *set, uint64_t *clr)
+{
+#ifdef UL_HAVE_MOUNT_API
+ struct libmnt_iter itr;
+ struct libmnt_opt *opt;
+
+ if (!ls || !ls->linux_map || !set || !clr)
+ return -EINVAL;
+
+ mnt_reset_iter(&itr, MNT_ITER_FORWARD);
+
+ while (mnt_optlist_next_opt(ls, &itr, &opt) == 0) {
+ if (ls->linux_map != opt->map)
+ continue;
+ if (!opt->ent || !opt->ent->id)
+ continue;
+ if (!is_wanted_opt(opt, ls->linux_map, MNT_OL_FLTR_DFLT))
+ continue;
+
+ if (opt->ent->mask & MNT_INVERT)
+ *clr |= flags_to_attrs( opt->ent->id );
+ else
+ *set |= flags_to_attrs( opt->ent->id );
+ }
+
+ DBG(OPTLIST, ul_debugobj(ls, "return attrs set=0x%08" PRIx64
+ ", clr=0x08%" PRIx64, *set, *clr));
+ return 0;
+
#endif
return 0;
}