public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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


  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