Whamcloud - gitweb
LU-14423 osd: recognize holes in osd_is_mapped()
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_io.c
index b9660d9..f99f625 100644 (file)
@@ -1156,6 +1156,14 @@ cont_map:
                                        total++;
                                        break;
                                }
+                               if ((map.m_flags & LDISKFS_MAP_UNWRITTEN) &&
+                                   !create) {
+                                       /* don't try to read allocated, but
+                                        * unwritten blocks, instead fill the
+                                        * patches with zeros in osd_do_bio() */
+                                       *(blocks + total) = 0;
+                                       continue;
+                               }
                                *(blocks + total) = map.m_pblk + c;
                                /* unmap any possible underlying
                                 * metadata from the block device
@@ -1327,6 +1335,16 @@ static int osd_is_mapped(struct dt_object *dt, __u64 offset,
                return 0;
 
        start = fe.fe_logical >> inode->i_blkbits;
+       if (fei.fi_extents_mapped == 0) {
+               /* a special case - no extent found at this offset and forward.
+                * we can consider this as a hole to EOF. it's safe to cache
+                * as other threads can not allocate/punch blocks this thread
+                * is working on (LDLM). */
+               cached_extent->start = block;
+               cached_extent->end = i_size_read(inode) >> inode->i_blkbits;
+               cached_extent->mapped = 0;
+               return 0;
+       }
 
        if (start > block) {
                cached_extent->start = block;
@@ -2162,6 +2180,10 @@ static int osd_declare_fallocate(const struct lu_env *env,
        if (mode & ~FALLOC_FL_KEEP_SIZE)
                RETURN(-EOPNOTSUPP);
 
+       /* disable fallocate completely */
+       if (osd_dev(dt->do_lu.lo_dev)->od_fallocate_zero_blocks < 0)
+               RETURN(-EOPNOTSUPP);
+
        LASSERT(th);
        LASSERT(inode);
 
@@ -2218,7 +2240,10 @@ static int osd_fallocate(const struct lu_env *env, struct dt_object *dt,
        boff = start >> inode->i_blkbits;
        blen = (ALIGN(end, 1 << inode->i_blkbits) >> inode->i_blkbits) - boff;
 
-       flags = LDISKFS_GET_BLOCKS_CREATE;
+       /* Create and mark new extents as either zero or unwritten */
+       flags = osd_dev(dt->do_lu.lo_dev)->od_fallocate_zero_blocks ?
+               LDISKFS_GET_BLOCKS_CREATE_ZERO :
+               LDISKFS_GET_BLOCKS_CREATE_UNWRIT_EXT;
        if (mode & FALLOC_FL_KEEP_SIZE)
                flags |= LDISKFS_GET_BLOCKS_KEEP_SIZE;