[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 08/12] xen/hypfs: support dynamic hypfs nodes
On 26.10.2020 10:13, Juergen Gross wrote: > Add a getsize() function pointer to struct hypfs_funcs for being able > to have dynamically filled entries without the need to take the hypfs > lock each time the contents are being generated. But a dynamic update causing a change in size will require _some_ lock, won't it? > --- a/xen/common/hypfs.c > +++ b/xen/common/hypfs.c > @@ -19,28 +19,29 @@ > CHECK_hypfs_dirlistentry; > #endif > > -#define DIRENTRY_NAME_OFF offsetof(struct xen_hypfs_dirlistentry, name) > -#define DIRENTRY_SIZE(name_len) \ > - (DIRENTRY_NAME_OFF + \ > - ROUNDUP((name_len) + 1, alignof(struct xen_hypfs_direntry))) > - > struct hypfs_funcs hypfs_dir_funcs = { > .read = hypfs_read_dir, > + .getsize = hypfs_getsize, > + .findentry = hypfs_dir_findentry, > }; > struct hypfs_funcs hypfs_leaf_ro_funcs = { > .read = hypfs_read_leaf, > + .getsize = hypfs_getsize, > }; > struct hypfs_funcs hypfs_leaf_wr_funcs = { > .read = hypfs_read_leaf, > .write = hypfs_write_leaf, > + .getsize = hypfs_getsize, > }; > struct hypfs_funcs hypfs_bool_wr_funcs = { > .read = hypfs_read_leaf, > .write = hypfs_write_bool, > + .getsize = hypfs_getsize, > }; > struct hypfs_funcs hypfs_custom_wr_funcs = { > .read = hypfs_read_leaf, > .write = hypfs_write_custom, > + .getsize = hypfs_getsize, > }; With the increasing number of fields that may (deliberately or by mistake) be NULL, should we gain some form of proactive guarding against calls through such pointers? > @@ -88,6 +93,23 @@ static void hypfs_unlock(void) > } > } > > +void *hypfs_alloc_dyndata(unsigned long size, unsigned long align) Will callers really need to specify (high) alignment values? IOW ... > +{ > + unsigned int cpu = smp_processor_id(); > + > + ASSERT(per_cpu(hypfs_locked, cpu) != hypfs_unlocked); > + ASSERT(per_cpu(hypfs_dyndata, cpu) == NULL); > + > + per_cpu(hypfs_dyndata, cpu) = _xzalloc(size, align); ... is xzalloc_bytes() not suitable for use here? > @@ -171,15 +193,34 @@ static int hypfs_get_path_user(char *buf, > return 0; > } > > +struct hypfs_entry *hypfs_dir_findentry(struct hypfs_entry_dir *dir, > + const char *name, > + unsigned int name_len) > +{ > + struct hypfs_entry *entry; > + > + list_for_each_entry ( entry, &dir->dirlist, list ) > + { > + int cmp = strncmp(name, entry->name, name_len); > + > + if ( cmp < 0 ) > + return ERR_PTR(-ENOENT); > + > + if ( !cmp && strlen(entry->name) == name_len ) > + return entry; > + } > + > + return ERR_PTR(-ENOENT); > +} > + > static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir, > const char *path) > { > const char *end; > struct hypfs_entry *entry; > unsigned int name_len; > - bool again = true; > > - while ( again ) > + for ( ;; ) Nit: Strictly speaking another blank is needed between the two semicolons. > @@ -275,22 +305,25 @@ int hypfs_read_leaf(const struct hypfs_entry *entry, > > l = container_of(entry, const struct hypfs_entry_leaf, e); > > - return copy_to_guest(uaddr, l->u.content, entry->size) ? -EFAULT: 0; > + return copy_to_guest(uaddr, l->u.content, entry->funcs->getsize(entry)) ? > + -EFAULT : 0; With the intended avoiding of locking, how is this ->getsize() guaranteed to not ... > @@ -298,7 +331,7 @@ static int hypfs_read(const struct hypfs_entry *entry, > goto out; > > ret = -ENOBUFS; > - if ( ulen < entry->size + sizeof(e) ) > + if ( ulen < size + sizeof(e) ) > goto out; ... invalidate the checking done here? (A similar risk looks to exist on the write path, albeit there we have at least the ->max_size checks, where I hope that field isn't mean to become dynamic as well.) Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |