1. 23 Sep, 2009 40 commits
    • Tao Ma's avatar
      ocfs2: Use buffer IO if we are appending a file. · b80474b4
      Tao Ma authored
      In ocfs2_file_aio_write, we will prevent direct io if
      we find that we are appending(changing i_size) and call
      generic_file_aio_write_nolock. But actually O_DIRECT flag
      is there and this function will call generic_file_direct_write
      eventually which will update i_size and leave di->i_size
      alone. The bug is
      http://oss.oracle.com/bugzilla/show_bug.cgi?id=1173.
      
      So this patch let ocfs2_direct_IO returns 0 directly if we
      are appending so that buffered write will be called and
      di->i_size get updated successfully. And this is also
      what we want in ocfs2_file_aio_write.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      b80474b4
    • Wengang Wang's avatar
      ocfs2: add spinlock protection when dealing with lockres->purge. · 83e32d90
      Wengang Wang authored
      when we check/modify lockres->purge, we should with the protection of lockres->spinlock.
      in dlm_purge_lockres(), the checking/modifying is not with the protectin.
      this patch fixes it.
      Signed-off-by: default avatarWengang Wang <wen.gang.wang@oracle.com>
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      83e32d90
    • Coly Li's avatar
      dlmglue.c: add missed mlog lines · d92bc512
      Coly Li authored
      This patch adds the missed mlog_exit() and mlog_exit_void() lines when routines
      return.
      Signed-off-by: default avatarColy Li <coly.li@suse.de>
      Acked-by: default avatarMark Fasheh <mfasheh@suse.com>
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      d92bc512
    • Sunil Mushran's avatar
      ocfs2: __ocfs2_abort() should not enable panic for local mounts · a2f2ddbf
      Sunil Mushran authored
      In a clustered setup, we have to panic the box on journal abort. This is
      because we don't have the facility to go hard readonly. With hard ro, another
      node would detect node failure and initiate recovery.
      
      Having said that, we shouldn't force panic if the volume is mounted locally.
      This patch defers the handling to the mount option, errors.
      Signed-off-by: default avatarSunil Mushran <sunil.mushran@oracle.com>
      Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
      a2f2ddbf
    • Tao Ma's avatar
      ocfs2: Add ioctl for reflink. · bd50873d
      Tao Ma authored
      The ioctl will take 3 parameters: old_path, new_path and
      preserve and call vfs_reflink. It is useful when we backport
      reflink features to old kernels.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      bd50873d
    • Tao Ma's avatar
      ocfs2: Enable refcount tree support. · 64871b8d
      Tao Ma authored
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      64871b8d
    • Tao Ma's avatar
      ocfs2: Implement ocfs2_reflink. · 09bf27a0
      Tao Ma authored
      Implement ocfs2_reflink.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      09bf27a0
    • Tao Ma's avatar
      ocfs2: Add preserve to reflink. · 0fe9b66c
      Tao Ma authored
      reflink has 2 options for the destination file:
      1. snapshot: reflink will attempt to preserve ownership, permissions,
         and all other security state in order to create a full snapshot.
      2. new file: it will acquire the data extent sharing but will see the
         file's security state and attributes initialized as a new file.
      
      So add the option to ocfs2.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      0fe9b66c
    • Tao Ma's avatar
      ocfs2: Create reflinked file in orphan dir. · bc13d347
      Tao Ma authored
      reflink is a very complicated process, so it can't be integrated
      into one transaction. So if the system panic in the operation, we
      may leave a unfinished inode in the destication directory.
      
      So we will try to create an inode in orphan_dir first, reflink it
      to the src file and then move it to the destication file in the end.
      In that way we won't be afraid of any corruption during the reflink.
      
      This patch adds 2 functions for orphan_dir operation:
      1. Create a new inode in orphand dir.
      2. Move an inode to a target dir.
      
      Note:
      fsck.ocfs2 should work for us to remove the unfinished file in the
      orphan_dir.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      bc13d347
    • Tao Ma's avatar
      ocfs2: Use proper parameter for some inode operation. · 19bd341f
      Tao Ma authored
      In order to make the original function more suitable for reflink,
      we modify the following inode operations. Both are tiny.
      
      1. ocfs2_mknod_locked only use dentry for mlog, so move it to
         the caller so that reflink can use it without dentry.
      2. ocfs2_prepare_orphan_dir only want inode to get its ip_blkno.
         So use ip_blkno instead.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      19bd341f
    • Tao Ma's avatar
      ocfs2: Make transaction extend more efficient. · c18b812d
      Tao Ma authored
      In ocfs2_extend_rotate_transaction, op_credits is the orignal
      credits in the handle and we only want to extend the credits
      for the rotation, but the old solution always double it. It
      is harmless for some minor operations, but for actions like
      reflink we may rotate tree many times and cause the credits
      increase dramatically. So this patch try to only increase
      the desired credits.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      c18b812d
    • Tao Ma's avatar
      ocfs2: Don't merge in 1st refcount ops of reflink. · 7540c1a7
      Tao Ma authored
      Actually the whole reflink will touch refcount tree 2 times:
      1. It will add the clusters in the extent record to the tree if it
         isn't refcounted before.
      2. It will add 1 refcount to these clusters when it add these
         extent records to the tree.
      
      So actually we shouldn't do merge in the 1st operation since the 2nd
      one will soon be called and we may have to split it again. Do a merge
      first and split soon is a waste of time. So we only merge in the 2nd
      round. This is done by adding a new internal __ocfs2_increase_refcount
      and call it with "not-merge" for 1st refcount operation in reflink.
      
      This also has a side-effect that we don't need to worry too much about
      the metadata allocation in the 2nd round since it will only merge and
      no split will happen for those records.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      7540c1a7
    • Tao Ma's avatar
      ocfs2: Modify removing xattr process for refcount. · ce9c5a54
      Tao Ma authored
      The old xattr value remove is quite simple, it just erase the
      tree and free the clusters. But as we have added refcount support,
      The process is a little complicated.
      
      We have to lock the refcount tree at the beginning, what's more,
      we may split the refcount tree in some cases, so meta/credits are
      needed.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      ce9c5a54
    • Tao Ma's avatar
      ocfs2: Add reflink support for xattr. · 2999d12f
      Tao Ma authored
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      2999d12f
    • Tao Ma's avatar
      ocfs2: Create an xattr indexed block if needed. · a7fe7a3a
      Tao Ma authored
      With reflink, there is a need that we create a new xattr indexed
      block from the very beginning. So add a new parameter for
      ocfs2_create_xattr_block.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      a7fe7a3a
    • Tao Ma's avatar
      ocfs2: Call refcount tree remove process properly. · 8b2c0dba
      Tao Ma authored
      Now with xattr refcount support, we need to check whether
      we have xattr refcounted before we remove the refcount tree.
      
      Now the mechanism is:
      1) Check whether i_clusters == 0, if no, exit.
      2) check whether we have i_xattr_loc in dinode. if yes, exit.
      2) Check whether we have inline xattr stored outside, if yes, exit.
      4) Remove the tree.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      8b2c0dba
    • Tao Ma's avatar
      ocfs2: Attach xattr clusters to refcount tree. · 0129241e
      Tao Ma authored
      In ocfs2, when xattr's value is larger than OCFS2_XATTR_INLINE_SIZE,
      it will be kept outside of the blocks we store xattr entry. And they
      are stored in a b-tree also. So this patch try to attach all these
      clusters to refcount tree also.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      0129241e
    • Tao Ma's avatar
      ocfs2: Abstract ocfs2 xattr tree extend rec iteration process. · 47bca495
      Tao Ma authored
      Currently we have ocfs2_iterate_xattr_buckets which can receive
      a para and a callback to iterate a series of bucket. It is good.
      But actually the 2 callers ocfs2_xattr_tree_list_index_block and
      ocfs2_delete_xattr_index_block are almost the same. The only
      difference is that the latter need to handle the extent record
      also. So add a new function named ocfs2_iterate_xattr_index_block.
      It can be given func callback which are used for exten record.
      So now we only have one iteration function for the xattr index
      block. Ane what's more, it is useful for our future reflink
      operations.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      47bca495
    • Tao Ma's avatar
      ocfs2: Abstract the creation of xattr block. · 5aea1f0e
      Tao Ma authored
      In xattr reflink, we also need to create xattr block, so
      abstract the process out.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      5aea1f0e
    • Tao Ma's avatar
      ocfs2: Remove inode from ocfs2_xattr_bucket_get_name_value. · fd68a894
      Tao Ma authored
      In ocfs2_xattr_bucket_get_name_value, actually we only use
      super_block. So use it.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      fd68a894
    • Tao Ma's avatar
      ocfs2: Add CoW support for xattr. · 492a8a33
      Tao Ma authored
      In order to make 2 transcation(xattr and cow) independent with each other,
      we CoW the whole xattr out in case we are setting them.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      492a8a33
    • Tao Ma's avatar
      ocfs2: Abstract duplicate clusters process in CoW. · 913580b4
      Tao Ma authored
      We currently use pagecache to duplicate clusters in CoW,
      but it isn't suitable for xattr case. So abstract it out
      so that the caller can decide which method it use.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      913580b4
    • Tao Ma's avatar
      ocfs2: Return extent flags for xattr value tree. · 1061f9c1
      Tao Ma authored
      With the new refcount tree, xattr value can also be refcounted
      among multiple files. So return the appropriate extent flags
      so that CoW can used it later.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      1061f9c1
    • Tao Ma's avatar
      ocfs2: handle file attributes issue for reflink. · a9063ab9
      Tao Ma authored
      A reflink creates a snapshot of a file, that means the attributes
      must be identical except for three exceptions - nlink, ino, and ctime.
      
      As for time changes, Here is a brief description:
      
      1. Source file:
         1) atime: Ignore. Let the lazy atime code handle that.
         2) mtime: don't touch.
         3) ctime: If we change the tree (adding REFCOUNTED to at least one
                   extent), update it.
      2. Destination file:
         1) atime: ignore.
         2) mtime: we want it to appear identical to the source.
         3) ctime: update.
      
      The idea here is that an ls -l will show the same time for the
      src and target - it shows mtime.  Backup software like rsync and tar
      will treat the new file correctly too.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      a9063ab9
    • Tao Ma's avatar
      ocfs2: Add normal functions for reflink a normal file's extents. · 110a045a
      Tao Ma authored
      2 major functions are added in this patch.
      
      ocfs2_attach_refcount_tree will create a new refcount tree to the
      old file if it doesn't have one and insert all the extent records
      to the tree if they are not refcounted.
      
      ocfs2_create_reflink_node will:
      1. set the refcount tree to the new file.
      2. call ocfs2_duplicate_extent_list which will iterate all the
         extents for the old file, insert it to the new file and increase
         the corresponding referennce count.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      110a045a
    • Tao Ma's avatar
      ocfs2: CoW a reflinked cluster when it is truncated. · 37f8a2bf
      Tao Ma authored
      When we truncate a file to a specific size which resides in a reflinked
      cluster, we need to CoW it since ocfs2_zero_range_for_truncate will
      zero the space after the size(just another type of write).
      
      So we add a "max_cpos" in ocfs2_refcount_cow so that it will stop when
      it hit the max cluster offset.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      37f8a2bf
    • Tao Ma's avatar
      ocfs2: Integrate CoW in file write. · 293b2f70
      Tao Ma authored
      When we use mmap, we CoW the refcountd clusters in
      ocfs2_write_begin_nolock. While for normal file
      io(including directio), we do CoW in
      ocfs2_prepare_inode_for_write.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      293b2f70
    • Tao Ma's avatar
      ocfs2: CoW refcount tree improvement. · 6ae23c55
      Tao Ma authored
      During CoW, if the old extent record is refcounted, we allocate
      som new clusters and do CoW. Actually we can have some improvement
      here. If the old extent has refcount=1, that means now it is only
      used by this file. So we don't need to allocate new clusters, just
      remove the refcounted flag and it is OK. We also have to remove
      it from the refcount tree while not deleting it.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      6ae23c55
    • Tao Ma's avatar
      ocfs2: Add CoW support. · 6f70fa51
      Tao Ma authored
      This patch try CoW support for a refcounted record.
      
      the whole process will be:
      1. Calculate how many clusters we need to CoW and where we start.
         Extents that are not completely encompassed by the write will
         be broken on 1MB boundaries.
      2. Do CoW for the clusters with the help of page cache.
      3. Change the b-tree structure with the new allocated clusters.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      6f70fa51
    • Tao Ma's avatar
      ocfs2: Decrement refcount when truncating refcounted extents. · bcbbb24a
      Tao Ma authored
      Add 'Decrement refcount for delete' in to the normal truncate
      process. So for a refcounted extent record, call refcount rec
      decrementation instead of cluster free.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      bcbbb24a
    • Tao Ma's avatar
      ocfs2: Add functions for extents refcounted. · 1aa75fea
      Tao Ma authored
      Add function ocfs2_mark_extent_refcounted which can mark
      an extent refcounted.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      1aa75fea
    • Tao Ma's avatar
      ocfs2: Add support of decrementing refcount for delete. · 1823cb0b
      Tao Ma authored
          Given a physical cpos and length, decrement the refcount
      in the tree. If the refcount for any portion of the extent goes
      to zero, that portion is queued for freeing.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      1823cb0b
    • Tao Ma's avatar
      ocfs2: Add support for incrementing refcount in the tree. · e73a819d
      Tao Ma authored
          Given a physical cpos and length, increment the refcount
      in the tree. If the extent has not been seen before, a refcount
      record is created for it. Refcount records may be merged or
      split by this operation.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      e73a819d
    • Tao Ma's avatar
      ocfs2: move tree path functions to alloc.h. · e2e9f608
      Tao Ma authored
      Now fs/ocfs2/alloc.c has more than 7000 lines. It contains our
      basic b-tree operation. Although we have already make our b-tree
      operation generic, the basic structrue ocfs2_path which is used
      to iterate one b-tree branch is still static and limited to only
      used in alloc.c. As refcount tree need them and I don't want to
      add any more b-tree unrelated code to alloc.c, export them out.
      
      Signed-off-by: Tao Ma <tao.ma@oracle.com> 
      e2e9f608
    • Tao Ma's avatar
      ocfs2: Add refcount b-tree as a new extent tree. · fe924415
      Tao Ma authored
      Add refcount b-tree as a new extent tree so that it can
      use the b-tree to store and maniuplate ocfs2_refcount_rec.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      fe924415
    • Tao Ma's avatar
      ocfs2: Abstract extent split process. · 555936bf
      Tao Ma authored
      ocfs2_mark_extent_written actually does the following things:
      1. check the parameters.
      2. initialize the left_path and split_rec.
      3. call __ocfs2_mark_extent_written. it will do:
         1) check the flags of unwritten
         2) do the real split work.
      The whole process is packed tightly somehow. So this patch
      will abstract 2 different functions so that future b-tree
      operation can work with it.
      
      1. __ocfs2_split_extent will accept path and split_rec and do
        the real split work.
      2. ocfs2_change_extent_flag will accept a new flag and initialize
         path and split_rec.
      
      So now ocfs2_mark_extent_written will do:
      1. check the parameters.
      2. call ocfs2_change_extent_flag.
         1) initalize the left_path and split_rec.
         2) check whether the new flags conflict with the old one.
         3) call __ocfs2_split_extent to do the split.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      555936bf
    • Tao Ma's avatar
      ocfs2: Wrap ocfs2_extent_contig in ocfs2_extent_tree. · 853a3a14
      Tao Ma authored
      Add a new operation eo_ocfs2_extent_contig int the extent tree's
      operations vector. So that with the new refcount tree, We want
      this so that refcount trees can always return CONTIG_NONE and
      prevent extent merging.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      853a3a14
    • Tao Ma's avatar
      ocfs2: Basic tree root operation. · 8bf396de
      Tao Ma authored
      Add basic refcount tree root operation.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      8bf396de
    • Tao Ma's avatar
      ocfs2: Add refcount tree lock mechanism. · 374a263e
      Tao Ma authored
      Implement locking around struct ocfs2_refcount_tree.  This protects
      all read/write operations on refcount trees.  ocfs2_refcount_tree
      has its own lock and its own caching_info, protecting buffers among
      multiple nodes.
      
      User must call ocfs2_lock_refcount_tree before his operation on
      the tree and unlock it after that.
      
      ocfs2_refcount_trees are referenced by the block number of the
      refcount tree root block, So we create an rb-tree on the ocfs2_super
      to look them up.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      374a263e
    • Tao Ma's avatar
      ocfs2: Add caching info for refcount tree. · c732eb16
      Tao Ma authored
      refcount tree should use its own caching info so that when
      we downconvert the refcount tree lock, we can drop all the
      cached buffer head.
      Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
      c732eb16