[CRIU] [PATCH] locks: fix up a device returned by stat() for btrfs (v2)
Pavel Emelyanov
xemul at parallels.com
Wed Sep 3 08:22:12 PDT 2014
On 09/03/2014 05:26 PM, Andrew Vagin wrote:
> BTRFS returns subvolume dev-id instead of superblock dev-id,
> in such case return device obtained from mountinfo (ie subvolume0).
>
> v2: fix up devices only for btrfs files.
>
> Reported-by: Mr Jenkins
> Signed-off-by: Andrew Vagin <avagin at openvz.org>
> ---
> file-lock.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 43 insertions(+), 3 deletions(-)
>
> diff --git a/file-lock.c b/file-lock.c
> index b6a511f..3da003e 100644
> --- a/file-lock.c
> +++ b/file-lock.c
> @@ -9,7 +9,10 @@
> #include "cr_options.h"
> #include "fdset.h"
> #include "files.h"
> +#include "fs-magic.h"
> #include "image.h"
> +#include "mount.h"
> +#include "proc_parse.h"
> #include "servicefd.h"
> #include "file-lock.h"
> #include "parasite.h"
> @@ -121,10 +124,43 @@ err:
> return ret;
> }
>
> -static inline bool lock_file_match(struct file_lock *fl, struct fd_parms *p)
> +static inline int lock_file_match(pid_t pid, int fd, struct file_lock *fl, struct fd_parms *p)
> {
> + struct mount_info *m;
> + dev_t dev = p->stat.st_dev;
> +
> + /* Get the right devices for BTRFS. Look at phys_stat_resolve_dev()
> + * for more details.
> + */
> + if (p->fs_type == BTRFS_SUPER_MAGIC) {
> + if (p->mnt_id == -1) {
> + char link[PATH_MAX], t[32];
> + struct ns_id *ns;
> + int ret;
> +
> + snprintf(t, sizeof(t), "/proc/%d/fd/%d", pid, fd);
> + ret = readlink(t, link, sizeof(link)) - 1;
> + if (ret < 0) {
> + pr_perror("Can't read link of fd %d", fd);
> + return -1;
> + } else if ((size_t)ret == sizeof(link)) {
> + pr_err("Buffer for read link of fd %d is too small\n", fd);
> + return -1;
> + }
> + link[ret] = 0;
> +
> + ns = lookup_nsid_by_mnt_id(p->mnt_id);
> + dev = phys_stat_resolve_dev(ns, p->stat.st_dev, link);
Can we use the phys_stat_dev_match() here? It's looks more
convenient for devices comparisons.
> + dev = kdev_to_odev(dev);
> + } else {
> + m = lookup_mnt_id(p->mnt_id);
> + BUG_ON(m == NULL);
> + dev = kdev_to_odev(m->s_dev);
> + }
> + }
> +
> return fl->i_no == p->stat.st_ino &&
> - makedev(fl->maj, fl->min) == p->stat.st_dev;
> + makedev(fl->maj, fl->min) == dev;
> }
>
> static int lock_check_fd(int lfd, struct file_lock *fl)
> @@ -164,9 +200,13 @@ static int lock_check_fd(int lfd, struct file_lock *fl)
> int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
> {
> struct file_lock *fl;
> + int ret;
>
> list_for_each_entry(fl, &file_lock_list, list) {
> - if (!lock_file_match(fl, p))
> + ret = lock_file_match(pid->real, fd, fl, p);
> + if (ret < 0)
> + return -1;
> + if (ret == 0)
> continue;
>
> if (!opts.handle_file_locks) {
>
More information about the CRIU
mailing list