1ae98043fSRyusuke Konishi // SPDX-License-Identifier: GPL-2.0+
236a580ebSKoji Sato /*
394ee1d91SRyusuke Konishi * NILFS direct block pointer.
436a580ebSKoji Sato *
536a580ebSKoji Sato * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
636a580ebSKoji Sato *
74b420ab4SRyusuke Konishi * Written by Koji Sato.
836a580ebSKoji Sato */
936a580ebSKoji Sato
1036a580ebSKoji Sato #include <linux/errno.h>
1136a580ebSKoji Sato #include "nilfs.h"
1236a580ebSKoji Sato #include "page.h"
1336a580ebSKoji Sato #include "direct.h"
1436a580ebSKoji Sato #include "alloc.h"
15c3a7abf0SRyusuke Konishi #include "dat.h"
1636a580ebSKoji Sato
nilfs_direct_dptrs(const struct nilfs_bmap * direct)1710ff885bSRyusuke Konishi static inline __le64 *nilfs_direct_dptrs(const struct nilfs_bmap *direct)
1836a580ebSKoji Sato {
1936a580ebSKoji Sato return (__le64 *)
2010ff885bSRyusuke Konishi ((struct nilfs_direct_node *)direct->b_u.u_data + 1);
2136a580ebSKoji Sato }
2236a580ebSKoji Sato
2336a580ebSKoji Sato static inline __u64
nilfs_direct_get_ptr(const struct nilfs_bmap * direct,__u64 key)2410ff885bSRyusuke Konishi nilfs_direct_get_ptr(const struct nilfs_bmap *direct, __u64 key)
2536a580ebSKoji Sato {
2625b8d7deSRyusuke Konishi return le64_to_cpu(*(nilfs_direct_dptrs(direct) + key));
2736a580ebSKoji Sato }
2836a580ebSKoji Sato
nilfs_direct_set_ptr(struct nilfs_bmap * direct,__u64 key,__u64 ptr)2910ff885bSRyusuke Konishi static inline void nilfs_direct_set_ptr(struct nilfs_bmap *direct,
3036a580ebSKoji Sato __u64 key, __u64 ptr)
3136a580ebSKoji Sato {
3225b8d7deSRyusuke Konishi *(nilfs_direct_dptrs(direct) + key) = cpu_to_le64(ptr);
3336a580ebSKoji Sato }
3436a580ebSKoji Sato
nilfs_direct_lookup(const struct nilfs_bmap * direct,__u64 key,int level,__u64 * ptrp)3510ff885bSRyusuke Konishi static int nilfs_direct_lookup(const struct nilfs_bmap *direct,
3636a580ebSKoji Sato __u64 key, int level, __u64 *ptrp)
3736a580ebSKoji Sato {
3836a580ebSKoji Sato __u64 ptr;
3936a580ebSKoji Sato
405ee58148SJiro SEKIBA if (key > NILFS_DIRECT_KEY_MAX || level != 1)
415ee58148SJiro SEKIBA return -ENOENT;
425ee58148SJiro SEKIBA ptr = nilfs_direct_get_ptr(direct, key);
435ee58148SJiro SEKIBA if (ptr == NILFS_BMAP_INVALID_PTR)
4436a580ebSKoji Sato return -ENOENT;
4536a580ebSKoji Sato
4636a580ebSKoji Sato *ptrp = ptr;
4736a580ebSKoji Sato return 0;
4836a580ebSKoji Sato }
4936a580ebSKoji Sato
nilfs_direct_lookup_contig(const struct nilfs_bmap * direct,__u64 key,__u64 * ptrp,unsigned int maxblocks)5010ff885bSRyusuke Konishi static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
51c3a7abf0SRyusuke Konishi __u64 key, __u64 *ptrp,
520c6c44cbSRyusuke Konishi unsigned int maxblocks)
53c3a7abf0SRyusuke Konishi {
54c3a7abf0SRyusuke Konishi struct inode *dat = NULL;
55c3a7abf0SRyusuke Konishi __u64 ptr, ptr2;
56c3a7abf0SRyusuke Konishi sector_t blocknr;
57c3a7abf0SRyusuke Konishi int ret, cnt;
58c3a7abf0SRyusuke Konishi
595ee58148SJiro SEKIBA if (key > NILFS_DIRECT_KEY_MAX)
605ee58148SJiro SEKIBA return -ENOENT;
615ee58148SJiro SEKIBA ptr = nilfs_direct_get_ptr(direct, key);
625ee58148SJiro SEKIBA if (ptr == NILFS_BMAP_INVALID_PTR)
63c3a7abf0SRyusuke Konishi return -ENOENT;
64c3a7abf0SRyusuke Konishi
6510ff885bSRyusuke Konishi if (NILFS_BMAP_USE_VBN(direct)) {
6610ff885bSRyusuke Konishi dat = nilfs_bmap_get_dat(direct);
67c3a7abf0SRyusuke Konishi ret = nilfs_dat_translate(dat, ptr, &blocknr);
68c3a7abf0SRyusuke Konishi if (ret < 0)
69*f69e8139SRyusuke Konishi goto dat_error;
70c3a7abf0SRyusuke Konishi ptr = blocknr;
71c3a7abf0SRyusuke Konishi }
72c3a7abf0SRyusuke Konishi
730c6c44cbSRyusuke Konishi maxblocks = min_t(unsigned int, maxblocks,
740c6c44cbSRyusuke Konishi NILFS_DIRECT_KEY_MAX - key + 1);
75c3a7abf0SRyusuke Konishi for (cnt = 1; cnt < maxblocks &&
76c3a7abf0SRyusuke Konishi (ptr2 = nilfs_direct_get_ptr(direct, key + cnt)) !=
77c3a7abf0SRyusuke Konishi NILFS_BMAP_INVALID_PTR;
78c3a7abf0SRyusuke Konishi cnt++) {
79c3a7abf0SRyusuke Konishi if (dat) {
80c3a7abf0SRyusuke Konishi ret = nilfs_dat_translate(dat, ptr2, &blocknr);
81c3a7abf0SRyusuke Konishi if (ret < 0)
82*f69e8139SRyusuke Konishi goto dat_error;
83c3a7abf0SRyusuke Konishi ptr2 = blocknr;
84c3a7abf0SRyusuke Konishi }
85c3a7abf0SRyusuke Konishi if (ptr2 != ptr + cnt)
86c3a7abf0SRyusuke Konishi break;
87c3a7abf0SRyusuke Konishi }
88c3a7abf0SRyusuke Konishi *ptrp = ptr;
89c3a7abf0SRyusuke Konishi return cnt;
90*f69e8139SRyusuke Konishi
91*f69e8139SRyusuke Konishi dat_error:
92*f69e8139SRyusuke Konishi if (ret == -ENOENT)
93*f69e8139SRyusuke Konishi ret = -EINVAL; /* Notify bmap layer of metadata corruption */
94*f69e8139SRyusuke Konishi return ret;
95c3a7abf0SRyusuke Konishi }
96c3a7abf0SRyusuke Konishi
9736a580ebSKoji Sato static __u64
nilfs_direct_find_target_v(const struct nilfs_bmap * direct,__u64 key)9810ff885bSRyusuke Konishi nilfs_direct_find_target_v(const struct nilfs_bmap *direct, __u64 key)
9936a580ebSKoji Sato {
10036a580ebSKoji Sato __u64 ptr;
10136a580ebSKoji Sato
10210ff885bSRyusuke Konishi ptr = nilfs_bmap_find_target_seq(direct, key);
10336a580ebSKoji Sato if (ptr != NILFS_BMAP_INVALID_PTR)
10436a580ebSKoji Sato /* sequential access */
10536a580ebSKoji Sato return ptr;
1067f00184eSRyusuke Konishi
10736a580ebSKoji Sato /* block group */
10810ff885bSRyusuke Konishi return nilfs_bmap_find_target_in_group(direct);
10936a580ebSKoji Sato }
11036a580ebSKoji Sato
nilfs_direct_insert(struct nilfs_bmap * bmap,__u64 key,__u64 ptr)11136a580ebSKoji Sato static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
11236a580ebSKoji Sato {
11336a580ebSKoji Sato union nilfs_bmap_ptr_req req;
1142e0c2c73SRyusuke Konishi struct inode *dat = NULL;
1152e0c2c73SRyusuke Konishi struct buffer_head *bh;
11636a580ebSKoji Sato int ret;
11736a580ebSKoji Sato
11836a580ebSKoji Sato if (key > NILFS_DIRECT_KEY_MAX)
11936a580ebSKoji Sato return -ENOENT;
12010ff885bSRyusuke Konishi if (nilfs_direct_get_ptr(bmap, key) != NILFS_BMAP_INVALID_PTR)
12136a580ebSKoji Sato return -EEXIST;
12236a580ebSKoji Sato
1232e0c2c73SRyusuke Konishi if (NILFS_BMAP_USE_VBN(bmap)) {
12410ff885bSRyusuke Konishi req.bpr_ptr = nilfs_direct_find_target_v(bmap, key);
1252e0c2c73SRyusuke Konishi dat = nilfs_bmap_get_dat(bmap);
12636a580ebSKoji Sato }
1272e0c2c73SRyusuke Konishi ret = nilfs_bmap_prepare_alloc_ptr(bmap, &req, dat);
1282e0c2c73SRyusuke Konishi if (!ret) {
1292e0c2c73SRyusuke Konishi /* ptr must be a pointer to a buffer head. */
1302e0c2c73SRyusuke Konishi bh = (struct buffer_head *)((unsigned long)ptr);
1312e0c2c73SRyusuke Konishi set_buffer_nilfs_volatile(bh);
13236a580ebSKoji Sato
1332e0c2c73SRyusuke Konishi nilfs_bmap_commit_alloc_ptr(bmap, &req, dat);
13410ff885bSRyusuke Konishi nilfs_direct_set_ptr(bmap, key, req.bpr_ptr);
13536a580ebSKoji Sato
1362e0c2c73SRyusuke Konishi if (!nilfs_bmap_dirty(bmap))
1372e0c2c73SRyusuke Konishi nilfs_bmap_set_dirty(bmap);
1382e0c2c73SRyusuke Konishi
1392e0c2c73SRyusuke Konishi if (NILFS_BMAP_USE_VBN(bmap))
140dc935be2SRyusuke Konishi nilfs_bmap_set_target_v(bmap, key, req.bpr_ptr);
1412e0c2c73SRyusuke Konishi
142be667377SRyusuke Konishi nilfs_inode_add_blocks(bmap->b_inode, 1);
14336a580ebSKoji Sato }
1442e0c2c73SRyusuke Konishi return ret;
14536a580ebSKoji Sato }
14636a580ebSKoji Sato
nilfs_direct_delete(struct nilfs_bmap * bmap,__u64 key)14736a580ebSKoji Sato static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
14836a580ebSKoji Sato {
14936a580ebSKoji Sato union nilfs_bmap_ptr_req req;
1502e0c2c73SRyusuke Konishi struct inode *dat;
15136a580ebSKoji Sato int ret;
15236a580ebSKoji Sato
1532e0c2c73SRyusuke Konishi if (key > NILFS_DIRECT_KEY_MAX ||
15410ff885bSRyusuke Konishi nilfs_direct_get_ptr(bmap, key) == NILFS_BMAP_INVALID_PTR)
15536a580ebSKoji Sato return -ENOENT;
15636a580ebSKoji Sato
1572e0c2c73SRyusuke Konishi dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
15810ff885bSRyusuke Konishi req.bpr_ptr = nilfs_direct_get_ptr(bmap, key);
15936a580ebSKoji Sato
1602e0c2c73SRyusuke Konishi ret = nilfs_bmap_prepare_end_ptr(bmap, &req, dat);
1612e0c2c73SRyusuke Konishi if (!ret) {
1622e0c2c73SRyusuke Konishi nilfs_bmap_commit_end_ptr(bmap, &req, dat);
16310ff885bSRyusuke Konishi nilfs_direct_set_ptr(bmap, key, NILFS_BMAP_INVALID_PTR);
164be667377SRyusuke Konishi nilfs_inode_sub_blocks(bmap->b_inode, 1);
1652e0c2c73SRyusuke Konishi }
1662e0c2c73SRyusuke Konishi return ret;
16736a580ebSKoji Sato }
16836a580ebSKoji Sato
nilfs_direct_seek_key(const struct nilfs_bmap * direct,__u64 start,__u64 * keyp)1695b20384fSRyusuke Konishi static int nilfs_direct_seek_key(const struct nilfs_bmap *direct, __u64 start,
1705b20384fSRyusuke Konishi __u64 *keyp)
1715b20384fSRyusuke Konishi {
1725b20384fSRyusuke Konishi __u64 key;
1735b20384fSRyusuke Konishi
1745b20384fSRyusuke Konishi for (key = start; key <= NILFS_DIRECT_KEY_MAX; key++) {
1755b20384fSRyusuke Konishi if (nilfs_direct_get_ptr(direct, key) !=
1765b20384fSRyusuke Konishi NILFS_BMAP_INVALID_PTR) {
1775b20384fSRyusuke Konishi *keyp = key;
1785b20384fSRyusuke Konishi return 0;
1795b20384fSRyusuke Konishi }
1805b20384fSRyusuke Konishi }
1815b20384fSRyusuke Konishi return -ENOENT;
1825b20384fSRyusuke Konishi }
1835b20384fSRyusuke Konishi
nilfs_direct_last_key(const struct nilfs_bmap * direct,__u64 * keyp)18410ff885bSRyusuke Konishi static int nilfs_direct_last_key(const struct nilfs_bmap *direct, __u64 *keyp)
18536a580ebSKoji Sato {
18636a580ebSKoji Sato __u64 key, lastkey;
18736a580ebSKoji Sato
18836a580ebSKoji Sato lastkey = NILFS_DIRECT_KEY_MAX + 1;
18936a580ebSKoji Sato for (key = NILFS_DIRECT_KEY_MIN; key <= NILFS_DIRECT_KEY_MAX; key++)
19036a580ebSKoji Sato if (nilfs_direct_get_ptr(direct, key) !=
19136a580ebSKoji Sato NILFS_BMAP_INVALID_PTR)
19236a580ebSKoji Sato lastkey = key;
19336a580ebSKoji Sato
19436a580ebSKoji Sato if (lastkey == NILFS_DIRECT_KEY_MAX + 1)
19536a580ebSKoji Sato return -ENOENT;
19636a580ebSKoji Sato
19736a580ebSKoji Sato *keyp = lastkey;
19836a580ebSKoji Sato
19936a580ebSKoji Sato return 0;
20036a580ebSKoji Sato }
20136a580ebSKoji Sato
nilfs_direct_check_insert(const struct nilfs_bmap * bmap,__u64 key)20236a580ebSKoji Sato static int nilfs_direct_check_insert(const struct nilfs_bmap *bmap, __u64 key)
20336a580ebSKoji Sato {
20436a580ebSKoji Sato return key > NILFS_DIRECT_KEY_MAX;
20536a580ebSKoji Sato }
20636a580ebSKoji Sato
nilfs_direct_gather_data(struct nilfs_bmap * direct,__u64 * keys,__u64 * ptrs,int nitems)20710ff885bSRyusuke Konishi static int nilfs_direct_gather_data(struct nilfs_bmap *direct,
20836a580ebSKoji Sato __u64 *keys, __u64 *ptrs, int nitems)
20936a580ebSKoji Sato {
21036a580ebSKoji Sato __u64 key;
21136a580ebSKoji Sato __u64 ptr;
21236a580ebSKoji Sato int n;
21336a580ebSKoji Sato
21436a580ebSKoji Sato if (nitems > NILFS_DIRECT_NBLOCKS)
21536a580ebSKoji Sato nitems = NILFS_DIRECT_NBLOCKS;
21636a580ebSKoji Sato n = 0;
21736a580ebSKoji Sato for (key = 0; key < nitems; key++) {
21836a580ebSKoji Sato ptr = nilfs_direct_get_ptr(direct, key);
21936a580ebSKoji Sato if (ptr != NILFS_BMAP_INVALID_PTR) {
22036a580ebSKoji Sato keys[n] = key;
22136a580ebSKoji Sato ptrs[n] = ptr;
22236a580ebSKoji Sato n++;
22336a580ebSKoji Sato }
22436a580ebSKoji Sato }
22536a580ebSKoji Sato return n;
22636a580ebSKoji Sato }
22736a580ebSKoji Sato
nilfs_direct_delete_and_convert(struct nilfs_bmap * bmap,__u64 key,__u64 * keys,__u64 * ptrs,int n)22836a580ebSKoji Sato int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
2293033342aSRyusuke Konishi __u64 key, __u64 *keys, __u64 *ptrs, int n)
23036a580ebSKoji Sato {
23136a580ebSKoji Sato __le64 *dptrs;
23236a580ebSKoji Sato int ret, i, j;
23336a580ebSKoji Sato
23436a580ebSKoji Sato /* no need to allocate any resource for conversion */
23536a580ebSKoji Sato
23636a580ebSKoji Sato /* delete */
2378acfbf09SPekka Enberg ret = bmap->b_ops->bop_delete(bmap, key);
23836a580ebSKoji Sato if (ret < 0)
23936a580ebSKoji Sato return ret;
24036a580ebSKoji Sato
24136a580ebSKoji Sato /* free resources */
24236a580ebSKoji Sato if (bmap->b_ops->bop_clear != NULL)
2438acfbf09SPekka Enberg bmap->b_ops->bop_clear(bmap);
24436a580ebSKoji Sato
24536a580ebSKoji Sato /* convert */
24610ff885bSRyusuke Konishi dptrs = nilfs_direct_dptrs(bmap);
24736a580ebSKoji Sato for (i = 0, j = 0; i < NILFS_DIRECT_NBLOCKS; i++) {
24836a580ebSKoji Sato if ((j < n) && (i == keys[j])) {
24936a580ebSKoji Sato dptrs[i] = (i != key) ?
25025b8d7deSRyusuke Konishi cpu_to_le64(ptrs[j]) :
25136a580ebSKoji Sato NILFS_BMAP_INVALID_PTR;
25236a580ebSKoji Sato j++;
25336a580ebSKoji Sato } else
25436a580ebSKoji Sato dptrs[i] = NILFS_BMAP_INVALID_PTR;
25536a580ebSKoji Sato }
25636a580ebSKoji Sato
2573033342aSRyusuke Konishi nilfs_direct_init(bmap);
25836a580ebSKoji Sato return 0;
25936a580ebSKoji Sato }
26036a580ebSKoji Sato
nilfs_direct_propagate(struct nilfs_bmap * bmap,struct buffer_head * bh)261583ada47SRyusuke Konishi static int nilfs_direct_propagate(struct nilfs_bmap *bmap,
26236a580ebSKoji Sato struct buffer_head *bh)
26336a580ebSKoji Sato {
2642e0c2c73SRyusuke Konishi struct nilfs_palloc_req oldreq, newreq;
2652e0c2c73SRyusuke Konishi struct inode *dat;
2662e0c2c73SRyusuke Konishi __u64 key;
2672e0c2c73SRyusuke Konishi __u64 ptr;
2682e0c2c73SRyusuke Konishi int ret;
26936a580ebSKoji Sato
2702e0c2c73SRyusuke Konishi if (!NILFS_BMAP_USE_VBN(bmap))
2712e0c2c73SRyusuke Konishi return 0;
2722e0c2c73SRyusuke Konishi
2732e0c2c73SRyusuke Konishi dat = nilfs_bmap_get_dat(bmap);
2742e0c2c73SRyusuke Konishi key = nilfs_bmap_data_get_key(bmap, bh);
27510ff885bSRyusuke Konishi ptr = nilfs_direct_get_ptr(bmap, key);
2762e0c2c73SRyusuke Konishi if (!buffer_nilfs_volatile(bh)) {
2772e0c2c73SRyusuke Konishi oldreq.pr_entry_nr = ptr;
2782e0c2c73SRyusuke Konishi newreq.pr_entry_nr = ptr;
2792e0c2c73SRyusuke Konishi ret = nilfs_dat_prepare_update(dat, &oldreq, &newreq);
2802e0c2c73SRyusuke Konishi if (ret < 0)
2812e0c2c73SRyusuke Konishi return ret;
2822e0c2c73SRyusuke Konishi nilfs_dat_commit_update(dat, &oldreq, &newreq,
2832e0c2c73SRyusuke Konishi bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
2842e0c2c73SRyusuke Konishi set_buffer_nilfs_volatile(bh);
28510ff885bSRyusuke Konishi nilfs_direct_set_ptr(bmap, key, newreq.pr_entry_nr);
2862e0c2c73SRyusuke Konishi } else
2872e0c2c73SRyusuke Konishi ret = nilfs_dat_mark_dirty(dat, ptr);
2882e0c2c73SRyusuke Konishi
2892e0c2c73SRyusuke Konishi return ret;
29036a580ebSKoji Sato }
29136a580ebSKoji Sato
nilfs_direct_assign_v(struct nilfs_bmap * direct,__u64 key,__u64 ptr,struct buffer_head ** bh,sector_t blocknr,union nilfs_binfo * binfo)29210ff885bSRyusuke Konishi static int nilfs_direct_assign_v(struct nilfs_bmap *direct,
29336a580ebSKoji Sato __u64 key, __u64 ptr,
29436a580ebSKoji Sato struct buffer_head **bh,
29536a580ebSKoji Sato sector_t blocknr,
29636a580ebSKoji Sato union nilfs_binfo *binfo)
29736a580ebSKoji Sato {
29810ff885bSRyusuke Konishi struct inode *dat = nilfs_bmap_get_dat(direct);
29936a580ebSKoji Sato union nilfs_bmap_ptr_req req;
30036a580ebSKoji Sato int ret;
30136a580ebSKoji Sato
30236a580ebSKoji Sato req.bpr_ptr = ptr;
3032e0c2c73SRyusuke Konishi ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
3042e0c2c73SRyusuke Konishi if (!ret) {
3052e0c2c73SRyusuke Konishi nilfs_dat_commit_start(dat, &req.bpr_req, blocknr);
30625b8d7deSRyusuke Konishi binfo->bi_v.bi_vblocknr = cpu_to_le64(ptr);
30725b8d7deSRyusuke Konishi binfo->bi_v.bi_blkoff = cpu_to_le64(key);
3082e0c2c73SRyusuke Konishi }
3092e0c2c73SRyusuke Konishi return ret;
31036a580ebSKoji Sato }
31136a580ebSKoji Sato
nilfs_direct_assign_p(struct nilfs_bmap * direct,__u64 key,__u64 ptr,struct buffer_head ** bh,sector_t blocknr,union nilfs_binfo * binfo)31210ff885bSRyusuke Konishi static int nilfs_direct_assign_p(struct nilfs_bmap *direct,
31336a580ebSKoji Sato __u64 key, __u64 ptr,
31436a580ebSKoji Sato struct buffer_head **bh,
31536a580ebSKoji Sato sector_t blocknr,
31636a580ebSKoji Sato union nilfs_binfo *binfo)
31736a580ebSKoji Sato {
31836a580ebSKoji Sato nilfs_direct_set_ptr(direct, key, blocknr);
31936a580ebSKoji Sato
32025b8d7deSRyusuke Konishi binfo->bi_dat.bi_blkoff = cpu_to_le64(key);
32136a580ebSKoji Sato binfo->bi_dat.bi_level = 0;
32273970316STetsuo Handa memset(binfo->bi_dat.bi_pad, 0, sizeof(binfo->bi_dat.bi_pad));
32336a580ebSKoji Sato
32436a580ebSKoji Sato return 0;
32536a580ebSKoji Sato }
32636a580ebSKoji Sato
nilfs_direct_assign(struct nilfs_bmap * bmap,struct buffer_head ** bh,sector_t blocknr,union nilfs_binfo * binfo)32736a580ebSKoji Sato static int nilfs_direct_assign(struct nilfs_bmap *bmap,
32836a580ebSKoji Sato struct buffer_head **bh,
32936a580ebSKoji Sato sector_t blocknr,
33036a580ebSKoji Sato union nilfs_binfo *binfo)
33136a580ebSKoji Sato {
33236a580ebSKoji Sato __u64 key;
33336a580ebSKoji Sato __u64 ptr;
33436a580ebSKoji Sato
33536a580ebSKoji Sato key = nilfs_bmap_data_get_key(bmap, *bh);
3361f5abe7eSRyusuke Konishi if (unlikely(key > NILFS_DIRECT_KEY_MAX)) {
337a1d0747aSJoe Perches nilfs_crit(bmap->b_inode->i_sb,
338a1d0747aSJoe Perches "%s (ino=%lu): invalid key: %llu",
339a1d0747aSJoe Perches __func__,
340feee880fSRyusuke Konishi bmap->b_inode->i_ino, (unsigned long long)key);
3411f5abe7eSRyusuke Konishi return -EINVAL;
3421f5abe7eSRyusuke Konishi }
34310ff885bSRyusuke Konishi ptr = nilfs_direct_get_ptr(bmap, key);
3441f5abe7eSRyusuke Konishi if (unlikely(ptr == NILFS_BMAP_INVALID_PTR)) {
345a1d0747aSJoe Perches nilfs_crit(bmap->b_inode->i_sb,
346a1d0747aSJoe Perches "%s (ino=%lu): invalid pointer: %llu",
347a1d0747aSJoe Perches __func__,
348feee880fSRyusuke Konishi bmap->b_inode->i_ino, (unsigned long long)ptr);
3491f5abe7eSRyusuke Konishi return -EINVAL;
3501f5abe7eSRyusuke Konishi }
35136a580ebSKoji Sato
352355c6b61SRyusuke Konishi return NILFS_BMAP_USE_VBN(bmap) ?
35310ff885bSRyusuke Konishi nilfs_direct_assign_v(bmap, key, ptr, bh, blocknr, binfo) :
35410ff885bSRyusuke Konishi nilfs_direct_assign_p(bmap, key, ptr, bh, blocknr, binfo);
35536a580ebSKoji Sato }
35636a580ebSKoji Sato
35736a580ebSKoji Sato static const struct nilfs_bmap_operations nilfs_direct_ops = {
35836a580ebSKoji Sato .bop_lookup = nilfs_direct_lookup,
359c3a7abf0SRyusuke Konishi .bop_lookup_contig = nilfs_direct_lookup_contig,
36036a580ebSKoji Sato .bop_insert = nilfs_direct_insert,
36136a580ebSKoji Sato .bop_delete = nilfs_direct_delete,
36236a580ebSKoji Sato .bop_clear = NULL,
36336a580ebSKoji Sato
36436a580ebSKoji Sato .bop_propagate = nilfs_direct_propagate,
36536a580ebSKoji Sato
36636a580ebSKoji Sato .bop_lookup_dirty_buffers = NULL,
36736a580ebSKoji Sato
36836a580ebSKoji Sato .bop_assign = nilfs_direct_assign,
36936a580ebSKoji Sato .bop_mark = NULL,
37036a580ebSKoji Sato
3715b20384fSRyusuke Konishi .bop_seek_key = nilfs_direct_seek_key,
37236a580ebSKoji Sato .bop_last_key = nilfs_direct_last_key,
3735b20384fSRyusuke Konishi
37436a580ebSKoji Sato .bop_check_insert = nilfs_direct_check_insert,
37536a580ebSKoji Sato .bop_check_delete = NULL,
37636a580ebSKoji Sato .bop_gather_data = nilfs_direct_gather_data,
37736a580ebSKoji Sato };
37836a580ebSKoji Sato
37936a580ebSKoji Sato
nilfs_direct_init(struct nilfs_bmap * bmap)3803033342aSRyusuke Konishi int nilfs_direct_init(struct nilfs_bmap *bmap)
38136a580ebSKoji Sato {
38236a580ebSKoji Sato bmap->b_ops = &nilfs_direct_ops;
38336a580ebSKoji Sato return 0;
38436a580ebSKoji Sato }
385