From: Alex Elder <elder@ieee.org>
To: "Yan, Zheng" <zheng.z.yan@intel.com>, ceph-devel@vger.kernel.org
Subject: Re: [PATCH] ceph: fix ceph_dir_llseek()
Date: Fri, 28 Feb 2014 08:05:03 -0600 [thread overview]
Message-ID: <5310978F.2000705@ieee.org> (raw)
In-Reply-To: <1393492047-18261-1-git-send-email-zheng.z.yan@intel.com>
On 02/27/2014 03:07 AM, Yan, Zheng wrote:
> Comparing offset with inode->i_sb->s_maxbytes doesn't make sense for
> directory. For a fragmented directory, offset (frag_t, off) can be
> larger than inode->i_sb->s_maxbytes.
>
> At the very beginning of ceph_dir_llseek(), local variable old_offset
> is initialized to parameter offset. This doesn't make sense neither.
> Old_offset should be ceph_make_fpos(fi->frag, fi->next_offset).
This looks OK to me, but I'm not as well-versed in the file system
code as I am in libceph and rbd. It looks like previously this
would produce problems if you ever did an llseek on a directory
that ended up in any fragment but the first.
I have one question/suggestion below, but otherwise:
Reviewed-by: Alex Elder <elder@linaro.org>
>
> Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
> ---
> fs/ceph/dir.c | 12 ++++++------
> fs/ceph/super.h | 2 +-
> 2 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
> index 45eda6d..a7eaf96 100644
> --- a/fs/ceph/dir.c
> +++ b/fs/ceph/dir.c
> @@ -190,7 +190,7 @@ more:
> if (last) {
> /* remember our position */
> fi->dentry = last;
> - fi->next_offset = di->offset;
> + fi->next_offset = fpos_off(di->offset);
> }
> dput(dentry);
> return 0;
> @@ -369,9 +369,9 @@ more:
> fi->next_offset = 0;
> off = fi->next_offset;
> }
> + fi->frag = frag;
> fi->offset = fi->next_offset;
> fi->last_readdir = req;
> - fi->frag = frag;
>
> if (req->r_reply_info.dir_end) {
> kfree(fi->last_name);
> @@ -474,7 +474,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
> {
> struct ceph_file_info *fi = file->private_data;
> struct inode *inode = file->f_mapping->host;
> - loff_t old_offset = offset;
> + loff_t old_offset = ceph_make_fpos(fi->frag, fi->next_offset);
Should this be named "next_offset" (or maybe "current_offset")?
It doesn't seem "old" to me, though I do realize it doesn't
necessarily represent where the "next" file position will be.
> loff_t retval;
>
> mutex_lock(&inode->i_mutex);
> @@ -491,7 +491,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
> goto out;
> }
>
> - if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
> + if (offset >= 0) {
> if (offset != file->f_pos) {
> file->f_pos = offset;
> file->f_version = 0;
> @@ -504,14 +504,14 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
> * seek to new frag, or seek prior to current chunk.
> */
> if (offset == 0 ||
> - fpos_frag(offset) != fpos_frag(old_offset) ||
> + fpos_frag(offset) != fi->frag ||
> fpos_off(offset) < fi->offset) {
> dout("dir_llseek dropping %p content\n", file);
> reset_readdir(fi);
> }
>
> /* bump dir_release_count if we did a forward seek */
> - if (offset > old_offset)
> + if (fpos_cmp(offset, old_offset) > 0)
> fi->dir_release_count--;
> }
> out:
> diff --git a/fs/ceph/super.h b/fs/ceph/super.h
> index d8801a9..70bb183 100644
> --- a/fs/ceph/super.h
> +++ b/fs/ceph/super.h
> @@ -577,7 +577,7 @@ struct ceph_file_info {
>
> /* readdir: position within a frag */
> unsigned offset; /* offset of last chunk, adjusted for . and .. */
> - u64 next_offset; /* offset of next chunk (last_name's + 1) */
> + unsigned next_offset; /* offset of next chunk (last_name's + 1) */
> char *last_name; /* last entry in previous chunk */
> struct dentry *dentry; /* next dentry (for dcache readdir) */
> int dir_release_count;
>
next prev parent reply other threads:[~2014-02-28 14:04 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-27 9:07 [PATCH] ceph: fix ceph_dir_llseek() Yan, Zheng
2014-02-28 14:05 ` Alex Elder [this message]
2014-03-01 0:14 ` Yan, Zheng
2014-03-02 1:06 ` Alex Elder
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=5310978F.2000705@ieee.org \
--to=elder@ieee.org \
--cc=ceph-devel@vger.kernel.org \
--cc=zheng.z.yan@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.