#include "page.h"
#include "direct.h"
#include "alloc.h"
+#include "dat.h"
static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct)
{
return 0;
}
+static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
+ __u64 key, __u64 *ptrp,
+ unsigned maxblocks)
+{
+ struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
+ struct inode *dat = NULL;
+ __u64 ptr, ptr2;
+ sector_t blocknr;
+ int ret, cnt;
+
+ if (key > NILFS_DIRECT_KEY_MAX ||
+ (ptr = nilfs_direct_get_ptr(direct, key)) ==
+ NILFS_BMAP_INVALID_PTR)
+ return -ENOENT;
+
+ if (NILFS_BMAP_USE_VBN(bmap)) {
+ dat = nilfs_bmap_get_dat(bmap);
+ ret = nilfs_dat_translate(dat, ptr, &blocknr);
+ if (ret < 0)
+ return ret;
+ ptr = blocknr;
+ }
+
+ maxblocks = min_t(unsigned, maxblocks, NILFS_DIRECT_KEY_MAX - key + 1);
+ for (cnt = 1; cnt < maxblocks &&
+ (ptr2 = nilfs_direct_get_ptr(direct, key + cnt)) !=
+ NILFS_BMAP_INVALID_PTR;
+ cnt++) {
+ if (dat) {
+ ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+ if (ret < 0)
+ return ret;
+ ptr2 = blocknr;
+ }
+ if (ptr2 != ptr + cnt)
+ break;
+ }
+ *ptrp = ptr;
+ return cnt;
+}
+
static __u64
nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key)
{
{
int ret;
- if (direct->d_ops->dop_find_target != NULL)
- req->bpr_ptr = direct->d_ops->dop_find_target(direct, key);
- ret = direct->d_bmap.b_pops->bpop_prepare_alloc_ptr(&direct->d_bmap,
- req);
+ if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
+ req->bpr_ptr = nilfs_direct_find_target_v(direct, key);
+ ret = nilfs_bmap_prepare_alloc_ptr(&direct->d_bmap, req);
if (ret < 0)
return ret;
bh = (struct buffer_head *)((unsigned long)ptr);
set_buffer_nilfs_volatile(bh);
- if (direct->d_bmap.b_pops->bpop_commit_alloc_ptr != NULL)
- direct->d_bmap.b_pops->bpop_commit_alloc_ptr(
- &direct->d_bmap, req);
+ nilfs_bmap_commit_alloc_ptr(&direct->d_bmap, req);
nilfs_direct_set_ptr(direct, key, req->bpr_ptr);
if (!nilfs_bmap_dirty(&direct->d_bmap))
nilfs_bmap_set_dirty(&direct->d_bmap);
- if (direct->d_ops->dop_set_target != NULL)
- direct->d_ops->dop_set_target(direct, key, req->bpr_ptr);
+ if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
+ nilfs_direct_set_target_v(direct, key, req->bpr_ptr);
}
static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
{
int ret;
- if (direct->d_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
- req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
- ret = direct->d_bmap.b_pops->bpop_prepare_end_ptr(
- &direct->d_bmap, req);
- if (ret < 0)
- return ret;
- }
-
- stats->bs_nblocks = 1;
- return 0;
+ req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
+ ret = nilfs_bmap_prepare_end_ptr(&direct->d_bmap, req);
+ if (!ret)
+ stats->bs_nblocks = 1;
+ return ret;
}
static void nilfs_direct_commit_delete(struct nilfs_direct *direct,
union nilfs_bmap_ptr_req *req,
__u64 key)
{
- if (direct->d_bmap.b_pops->bpop_commit_end_ptr != NULL)
- direct->d_bmap.b_pops->bpop_commit_end_ptr(
- &direct->d_bmap, req);
+ nilfs_bmap_commit_end_ptr(&direct->d_bmap, req);
nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
}
}
int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
- __u64 key, __u64 *keys, __u64 *ptrs,
- int n, __u64 low, __u64 high)
+ __u64 key, __u64 *keys, __u64 *ptrs, int n)
{
struct nilfs_direct *direct;
__le64 *dptrs;
dptrs[i] = NILFS_BMAP_INVALID_PTR;
}
- nilfs_direct_init(bmap, low, high);
-
+ nilfs_direct_init(bmap);
return 0;
}
if (!buffer_nilfs_volatile(bh)) {
oldreq.bpr_ptr = ptr;
newreq.bpr_ptr = ptr;
- ret = nilfs_bmap_prepare_update(&direct->d_bmap, &oldreq,
- &newreq);
+ ret = nilfs_bmap_prepare_update_v(&direct->d_bmap, &oldreq,
+ &newreq);
if (ret < 0)
return ret;
- nilfs_bmap_commit_update(&direct->d_bmap, &oldreq, &newreq);
+ nilfs_bmap_commit_update_v(&direct->d_bmap, &oldreq, &newreq);
set_buffer_nilfs_volatile(bh);
nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr);
} else
static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
struct buffer_head *bh)
{
- struct nilfs_direct *direct;
+ struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
- direct = (struct nilfs_direct *)bmap;
- return (direct->d_ops->dop_propagate != NULL) ?
- direct->d_ops->dop_propagate(direct, bh) :
- 0;
+ return NILFS_BMAP_USE_VBN(bmap) ?
+ nilfs_direct_propagate_v(direct, bh) : 0;
}
static int nilfs_direct_assign_v(struct nilfs_direct *direct,
return -EINVAL;
}
- return direct->d_ops->dop_assign(direct, key, ptr, bh,
- blocknr, binfo);
+ return NILFS_BMAP_USE_VBN(bmap) ?
+ nilfs_direct_assign_v(direct, key, ptr, bh, blocknr, binfo) :
+ nilfs_direct_assign_p(direct, key, ptr, bh, blocknr, binfo);
}
static const struct nilfs_bmap_operations nilfs_direct_ops = {
.bop_lookup = nilfs_direct_lookup,
+ .bop_lookup_contig = nilfs_direct_lookup_contig,
.bop_insert = nilfs_direct_insert,
.bop_delete = nilfs_direct_delete,
.bop_clear = NULL,
};
-static const struct nilfs_direct_operations nilfs_direct_ops_v = {
- .dop_find_target = nilfs_direct_find_target_v,
- .dop_set_target = nilfs_direct_set_target_v,
- .dop_propagate = nilfs_direct_propagate_v,
- .dop_assign = nilfs_direct_assign_v,
-};
-
-static const struct nilfs_direct_operations nilfs_direct_ops_p = {
- .dop_find_target = NULL,
- .dop_set_target = NULL,
- .dop_propagate = NULL,
- .dop_assign = nilfs_direct_assign_p,
-};
-
-int nilfs_direct_init(struct nilfs_bmap *bmap, __u64 low, __u64 high)
+int nilfs_direct_init(struct nilfs_bmap *bmap)
{
- struct nilfs_direct *direct;
-
- direct = (struct nilfs_direct *)bmap;
bmap->b_ops = &nilfs_direct_ops;
- bmap->b_low = low;
- bmap->b_high = high;
- switch (bmap->b_inode->i_ino) {
- case NILFS_DAT_INO:
- direct->d_ops = &nilfs_direct_ops_p;
- break;
- default:
- direct->d_ops = &nilfs_direct_ops_v;
- break;
- }
-
return 0;
}