From: Dave Hansen <dave@linux.vnet.ibm.com>
To: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: containers <containers@lists.linux-foundation.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
hch@infradead.org, Ingo Molnar <mingo@elte.hu>,
Alexey Dobriyan <adobriyan@gmail.com>
Subject: Re: [RFC][PATCH 5/8] add f_op for checkpointability
Date: Fri, 27 Feb 2009 18:51:43 -0800 [thread overview]
Message-ID: <1235789503.26788.413.camel@nimitz> (raw)
In-Reply-To: <20090228021412.GD19872@us.ibm.com>
On Fri, 2009-02-27 at 18:14 -0800, Sukadev Bhattiprolu wrote:
> | -int cr_file_supported(struct file *file)
> | +typedef int (do_checkpoint_t)(struct file *, struct cr_ctx *,
> | + struct cr_hdr_fd *);
> | +
> | +int generic_file_checkpoint(struct file *file, struct cr_ctx *ctx,
> | + struct cr_hdr_fd *hh)
> | +{
> | + /*
> | + * A NULL hh means to make a trial run not
> | + * actually writing data. Just determine
> | + * if the file is checkpointable.
> | + */
> | + if (!hh)
> | + return 0;
> | +
> | + hh->f_flags = file->f_flags;
> | + hh->f_mode = file->f_mode;
> | + hh->f_pos = file->f_pos;
> | + hh->f_version = file->f_version;
> | + /* FIX: need also file->uid, file->gid, file->f_owner, etc */
> | +
> | + return 0;
> | +}
> | +
> | +do_checkpoint_t *cr_file_get_func(struct file *file)
> | {
>
> Do we really need this helper ? IOW do callers need this function pointer
> itself ? Or can we have a more generic helper that callers can use both
> check if checkpoint is possible (pass NULL in ctx and hh) and to actually
> checkpoint. Something like:
That helper is there because I overload that f_op->checkpoint for both
the "is this file checkpointable" function and the "checkpoint this
file" operation.
> int cr_file_checkpoint(file, ctx, hh)
> {
> int rc = -1;
>
> if (!cr_fs_checkpointable(fstype))
> return rc;
>
> if (!cr_file_checkpointable(file))
> return rc;
>
> if (special_file(file))
> return rc;
>
> op = file->f_op->checkpoint;
> if (!op)
> op = generic_file_checkpoint;
>
> return (*op)(file, ctx, hh);
> }
First thing you have to be careful about is that the f_op should be able
to override *everything*. So it has to be first, always.
The other part is that I'd prefer not to call check (a la !
cr_file_checkpointable()) then try to checkpoint a second later, since
we share the implementation between the two here.
You are probably right that we should probably be able to do this:
int cr_file_checkpointable(file)
{
return !cr_file_checkpoint(file, NULL, NULL);
}
I'll look into that and see how natural it is to implement.
> | struct inode *inode = file->f_dentry->d_inode;
> | struct file_system_type *fs_type = inode->i_sb->s_type;
> |
> | - if (fs_is_cr_able(fs_type))
> | - return 0;
> | + if (file->f_op->checkpoint)
> | + return file->f_op->checkpoint;
> | +
> | + if (!fs_is_cr_able(fs_type))
> | + return NULL;
> |
> | if (special_file(inode->i_mode))
> | - return 0;
> | + return NULL;
> |
> | - return 1;
> | + return generic_file_checkpoint;
> | +}
> | +
> | +int cr_file_supported(struct file *file)
> | +{
> | + do_checkpoint_t *func = cr_file_get_func(file);
> | +
> | + if (func)
> | + return !func(file, NULL, NULL);
> | +
> | + return 0;
> | }
> |
> | /* cr_write_fd_data - dump the state of a given file pointer */
> | static int cr_write_fd_data(struct cr_ctx *ctx, struct file *file, int parent)
> | {
> | + do_checkpoint_t *ckpt_func;
> | struct cr_hdr h;
> | struct cr_hdr_fd *hh = cr_hbuf_get(ctx, sizeof(*hh));
> | - struct dentry *dent = file->f_dentry;
> | - struct inode *inode = dent->d_inode;
> | - enum fd_type fd_type;
> | int ret;
> |
> | h.type = CR_HDR_FD_DATA;
> | h.len = sizeof(*hh);
> | h.parent = parent;
> |
> | - hh->f_flags = file->f_flags;
> | - hh->f_mode = file->f_mode;
> | - hh->f_pos = file->f_pos;
> | - hh->f_version = file->f_version;
> | - /* FIX: need also file->uid, file->gid, file->f_owner, etc */
> | -
> | - switch (inode->i_mode & S_IFMT) {
> | - case S_IFREG:
> | - fd_type = CR_FD_FILE;
> | - break;
> | - case S_IFDIR:
> | - fd_type = CR_FD_DIR;
> | - break;
> | - default:
> | - cr_hbuf_put(ctx, sizeof(*hh));
> | - return -EBADF;
> | - }
> | + ckpt_func = cr_file_get_func(file);
> | + ret = -EBADF;
> | + if (!ckpt_func)
> | + goto out;
> |
> | - /* FIX: check if the file/dir/link is unlinked */
> | - hh->fd_type = fd_type;
> | + ret = ckpt_func(file, ctx, hh);
> | + if (ret)
> | + goto out;
>
> So we can combine these two steps into just one ?
>
> ret = -EBADF;
> hh->fd_type = fd_type;
> if (cr_file_checkpoint(file, ctx, hh))
> goto out;
We could but it would be harder to read. :)
I really don't like operational things inside if()s like that. I think
it kinda hides important code.
Thanks for taking the time to look at this, Suka.
-- Dave
next prev parent reply other threads:[~2009-02-28 2:51 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-27 20:34 [RFC][PATCH 1/8] kill '_data' in cr_hdr_fd_data name Dave Hansen
2009-02-27 20:34 ` [RFC][PATCH 2/8] breakout fdinfo sprintf() into its own function Dave Hansen
2009-02-27 20:56 ` Vegard Nossum
2009-02-27 21:23 ` Dave Hansen
2009-02-27 20:34 ` [RFC][PATCH 3/8] create fs flags to mark c/r supported fs's Dave Hansen
2009-02-27 21:16 ` Alexey Dobriyan
2009-02-27 21:20 ` Dave Hansen
2009-02-27 20:34 ` [RFC][PATCH 4/8] file c/r: expose functions to query fs support Dave Hansen
2009-02-27 21:14 ` Sukadev Bhattiprolu
2009-02-27 21:24 ` Dave Hansen
2009-02-27 21:32 ` Dave Hansen
2009-02-28 1:33 ` Sukadev Bhattiprolu
2009-02-27 20:34 ` [RFC][PATCH 5/8] add f_op for checkpointability Dave Hansen
2009-02-28 2:14 ` Sukadev Bhattiprolu
2009-02-28 2:51 ` Dave Hansen [this message]
2009-02-28 20:53 ` Christoph Hellwig
2009-02-28 21:37 ` Dave Hansen
2009-03-01 15:19 ` Serge E. Hallyn
2009-03-02 17:05 ` Dave Hansen
2009-03-03 13:15 ` Christoph Hellwig
2009-03-20 21:13 ` Dave Hansen
2009-03-20 21:30 ` Oren Laadan
2009-02-27 20:34 ` [RFC][PATCH 6/8] mark /dev/null and zero as checkpointable Dave Hansen
2009-02-27 20:34 ` [RFC][PATCH 7/8] add c/r info to fdinfo Dave Hansen
2009-02-27 20:34 ` [RFC][PATCH 8/8] check files for checkpointability Dave Hansen
2009-02-28 2:57 ` Sukadev Bhattiprolu
2009-03-01 17:00 ` Serge E. Hallyn
2009-03-04 23:41 ` Dave Hansen
2009-03-01 19:43 ` Serge E. Hallyn
2009-03-02 13:37 ` Serge E. Hallyn
2009-03-02 15:56 ` Dave Hansen
2009-03-02 15:59 ` Nathan Lynch
2009-03-02 16:27 ` Dave Hansen
2009-03-02 17:22 ` Nathan Lynch
2009-03-02 17:30 ` Dave Hansen
2009-03-02 17:44 ` Serge E. Hallyn
2009-03-02 17:58 ` Dave Hansen
2009-03-02 18:13 ` Dave Hansen
2009-03-02 18:35 ` Serge E. Hallyn
2009-03-05 8:20 ` Cedric Le Goater
2009-03-02 16:28 ` Serge E. Hallyn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1235789503.26788.413.camel@nimitz \
--to=dave@linux.vnet.ibm.com \
--cc=adobriyan@gmail.com \
--cc=containers@lists.linux-foundation.org \
--cc=hch@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=sukadev@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox