static unsigned long
nilfs_cpfile_get_blkoff(const struct inode *cpfile, __u64 cno)
{
- __u64 tcno;
-
- BUG_ON(cno == 0); /* checkpoint number 0 is invalid */
- tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1;
+ __u64 tcno = cno + NILFS_MDT(cpfile)->mi_first_entry_offset - 1;
do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile));
return (unsigned long)tcno;
}
struct nilfs_checkpoint *cp = kaddr + bh_offset(bh);
unsigned int count;
- BUG_ON(le32_to_cpu(cp->cp_checkpoints_count) < n);
+ WARN_ON(le32_to_cpu(cp->cp_checkpoints_count) < n);
count = le32_to_cpu(cp->cp_checkpoints_count) - n;
cp->cp_checkpoints_count = cpu_to_le32(count);
return count;
* %-ENOMEM - Insufficient amount of memory available.
*
* %-ENOENT - No such checkpoint.
+ *
+ * %-EINVAL - invalid checkpoint.
*/
int nilfs_cpfile_get_checkpoint(struct inode *cpfile,
__u64 cno,
void *kaddr;
int ret;
- BUG_ON(cno < 1 || cno > nilfs_mdt_cno(cpfile) ||
- (cno < nilfs_mdt_cno(cpfile) && create));
+ if (unlikely(cno < 1 || cno > nilfs_mdt_cno(cpfile) ||
+ (cno < nilfs_mdt_cno(cpfile) && create)))
+ return -EINVAL;
down_write(&NILFS_MDT(cpfile)->mi_sem);
unsigned long tnicps;
int ret, ncps, nicps, count, i;
- if ((start == 0) || (start > end)) {
- printk(KERN_CRIT "%s: start = %llu, end = %llu\n",
- __func__,
- (unsigned long long)start,
- (unsigned long long)end);
- BUG();
+ if (unlikely(start == 0 || start > end)) {
+ printk(KERN_ERR "%s: invalid range of checkpoint numbers: "
+ "[%llu, %llu)\n", __func__,
+ (unsigned long long)start, (unsigned long long)end);
+ return -EINVAL;
}
/* cannot delete the latest checkpoint */
ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
if (ret < 0) {
if (ret != -ENOENT)
- goto out_sem;
+ goto out_header;
/* skip hole */
ret = 0;
continue;
cpfile, cno, cp_bh, kaddr);
nicps = 0;
for (i = 0; i < ncps; i++, cp = (void *)cp + cpsz) {
- BUG_ON(nilfs_checkpoint_snapshot(cp));
+ WARN_ON(nilfs_checkpoint_snapshot(cp));
if (!nilfs_checkpoint_invalid(cp)) {
nilfs_checkpoint_set_invalid(cp);
nicps++;
continue;
printk(KERN_ERR "%s: cannot delete block\n",
__func__);
- goto out_sem;
+ goto out_header;
}
}
nilfs_mdt_mark_dirty(cpfile);
kunmap_atomic(kaddr, KM_USER0);
}
+
+ out_header:
brelse(header_bh);
out_sem:
ci->ci_next = le64_to_cpu(cp->cp_snapshot_list.ssl_next);
}
-static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 cno,
+static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
struct nilfs_cpinfo *ci, size_t nci)
{
struct nilfs_checkpoint *cp;
struct buffer_head *bh;
size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size;
- __u64 cur_cno = nilfs_mdt_cno(cpfile);
+ __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop;
void *kaddr;
int n, ret;
int ncps, i;
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
down_read(&NILFS_MDT(cpfile)->mi_sem);
for (n = 0; cno < cur_cno && n < nci; cno += ncps) {
}
ret = n;
+ if (n > 0)
+ *cnop = ci[n - 1].ci_cno + 1;
out:
up_read(&NILFS_MDT(cpfile)->mi_sem);
{
switch (mode) {
case NILFS_CHECKPOINT:
- return nilfs_cpfile_do_get_cpinfo(cpfile, *cnop, ci, nci);
+ return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, ci, nci);
case NILFS_SNAPSHOT:
return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, ci, nci);
default:
int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno)
{
struct nilfs_cpinfo ci;
+ __u64 tcno = cno;
ssize_t nci;
int ret;
- /* checkpoint number 0 is invalid */
- if (cno == 0)
- return -ENOENT;
- nci = nilfs_cpfile_do_get_cpinfo(cpfile, cno, &ci, 1);
+ nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, 1);
if (nci < 0)
return nci;
else if (nci == 0 || ci.ci_cno != cno)
void *kaddr;
int ret;
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
down_write(&NILFS_MDT(cpfile)->mi_sem);
ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
void *kaddr;
int ret;
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
down_write(&NILFS_MDT(cpfile)->mi_sem);
ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
void *kaddr;
int ret;
+ if (cno == 0)
+ return -ENOENT; /* checkpoint number 0 is invalid */
down_read(&NILFS_MDT(cpfile)->mi_sem);
ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh);