回复:[PATCH] ovl: improving copy-up efficiency for sparse file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 ---- 在 星期五, 2019-10-04 21:20:30 Chengguang Xu <cgxu519@xxxxxxxxxxxx> 撰写 ----
 > Current copy-up is not efficient for sparse file,
 > It's not only slow but also wasting more disk space
 > when the target lower file has huge hole inside.
 > This patch tries to recognize file hole and skip it
 > during copy-up.
 > 
 > In detail, this optimization checks the hole according
 > to copy-up chunk size so it may not recognize all kind
 > of holes in the file. However, it is easy to implement
 > and will be enough for most of the time.
 > 
 > Additionally, this optimization relies on lseek(2)
 > SEEK_DATA implementation, so for some specific
 > filesystems which do not support this feature
 > will behave as before on copy-up.
 > 
 > Signed-off-by: Chengguang Xu <cgxu519@xxxxxxxxxxxx>
 > ---

Any better idea or suggestion for this?


Thanks,
Chengguang


 >  fs/overlayfs/copy_up.c | 15 ++++++++++++++-
 >  1 file changed, 14 insertions(+), 1 deletion(-)
 > 
 > diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
 > index b801c6353100..028033c9f021 100644
 > --- a/fs/overlayfs/copy_up.c
 > +++ b/fs/overlayfs/copy_up.c
 > @@ -144,10 +144,11 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
 >          goto out;
 >      /* Couldn't clone, so now we try to copy the data */
 >  
 > -    /* FIXME: copy up sparse files efficiently */
 >      while (len) {
 >          size_t this_len = OVL_COPY_UP_CHUNK_SIZE;
 >          long bytes;
 > +        loff_t old_next_data_pos;
 > +        loff_t hole_len;
 >  
 >          if (len < this_len)
 >              this_len = len;
 > @@ -157,6 +158,18 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
 >              break;
 >          }
 >  
 > +        old_next_data_pos = vfs_llseek(old_file, old_pos, SEEK_DATA);
 > +        if (old_next_data_pos >= old_pos + OVL_COPY_UP_CHUNK_SIZE) {
 > +            hole_len = (old_next_data_pos - old_pos) /
 > +                OVL_COPY_UP_CHUNK_SIZE * OVL_COPY_UP_CHUNK_SIZE;
 > +            old_pos += hole_len;
 > +            new_pos += hole_len;
 > +            len -= hole_len;
 > +            continue;
 > +        } else if (old_next_data_pos == -ENXIO) {
 > +            break;
 > +        }
 > +
 >          bytes = do_splice_direct(old_file, &old_pos,
 >                       new_file, &new_pos,
 >                       this_len, SPLICE_F_MOVE);
 > -- 
 > 2.21.0
 > 
 > 
 >





[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux