/** * ubifs_ro_mode - switch UBIFS to read read-only mode. * @c: UBIFS file-system description object * @err: error code which is the reason of switching to R/O mode */ void ubifs_ro_mode(struct ubifs_info *c, int err) { if (!c->ro_error) { c->ro_error = 1; c->no_chk_data_crc = 0; c->vfs_sb->s_flags |= SB_RDONLY; ubifs_warn(c, "switched to read-only mode, error %d", err); dump_stack(); } }
/** * next_sqnum - get next sequence number. * @c: UBIFS file-system description object */ static unsigned long long next_sqnum(struct ubifs_info *c) { unsigned long long sqnum; spin_lock(&c->cnt_lock); sqnum = ++c->max_sqnum; spin_unlock(&c->cnt_lock); if (unlikely(sqnum >= SQNUM_WARN_WATERMARK)) { if (sqnum >= SQNUM_WATERMARK) { ubifs_err("sequence number overflow %llu, end of life", sqnum); ubifs_ro_mode(c, -EINVAL); } ubifs_warn("running out of sequence numbers, end of life soon"); } return sqnum; }
/** * ubifs_compress - compress data. * @in_buf: data to compress * @in_len: length of the data to compress * @out_buf: output buffer where compressed data should be stored * @out_len: output buffer length is returned here * @compr_type: type of compression to use on enter, actually used compression * type on exit * * This function compresses input buffer @in_buf of length @in_len and stores * the result in the output buffer @out_buf and the resulting length in * @out_len. If the input buffer does not compress, it is just copied to the * @out_buf. The same happens if @compr_type is %UBIFS_COMPR_NONE or if * compression error occurred. * * Note, if the input buffer was not compressed, it is copied to the output * buffer and %UBIFS_COMPR_NONE is returned in @compr_type. */ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, int *compr_type) { int err; struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; if (*compr_type == UBIFS_COMPR_NONE) goto no_compr; /* If the input data is small, do not even try to compress it */ if (in_len < UBIFS_MIN_COMPR_LEN) goto no_compr; if (compr->comp_mutex) mutex_lock(compr->comp_mutex); err = crypto_comp_compress(compr->cc, in_buf, in_len, out_buf, (unsigned int *)out_len); if (compr->comp_mutex) mutex_unlock(compr->comp_mutex); if (unlikely(err)) { ubifs_warn("cannot compress %d bytes, compressor %s, " "error %d, leave data uncompressed", in_len, compr->name, err); goto no_compr; } /* * If the data compressed only slightly, it is better to leave it * uncompressed to improve read speed. */ if (in_len - *out_len < UBIFS_MIN_COMPRESS_DIFF) goto no_compr; if (*compr_type == UBIFS_COMPR_LZO999) *compr_type = UBIFS_COMPR_LZO; return; no_compr: memcpy(out_buf, in_buf, in_len); *out_len = in_len; *compr_type = UBIFS_COMPR_NONE; }
void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, int *compr_type) { int err; struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; if (*compr_type == UBIFS_COMPR_NONE) goto no_compr; if (in_len < UBIFS_MIN_COMPR_LEN) goto no_compr; if (compr->comp_mutex) mutex_lock(compr->comp_mutex); err = crypto_comp_compress(compr->cc, in_buf, in_len, out_buf, (unsigned int *)out_len); if (compr->comp_mutex) mutex_unlock(compr->comp_mutex); if (unlikely(err)) { ubifs_warn("cannot compress %d bytes, compressor %s, " "error %d, leave data uncompressed", in_len, compr->name, err); goto no_compr; } if (in_len - *out_len < UBIFS_MIN_COMPRESS_DIFF) goto no_compr; return; no_compr: memcpy(out_buf, in_buf, in_len); *out_len = in_len; *compr_type = UBIFS_COMPR_NONE; }
/** * make_reservation - reserve journal space. * @c: UBIFS file-system description object * @jhead: journal head * @len: how many bytes to reserve * * This function makes space reservation in journal head @jhead. The function * takes the commit lock and locks the journal head, and the caller has to * unlock the head and finish the reservation with 'finish_reservation()'. * Returns zero in case of success and a negative error code in case of * failure. * * Note, the journal head may be unlocked as soon as the data is written, while * the commit lock has to be released after the data has been added to the * TNC. */ static int make_reservation(struct ubifs_info *c, int jhead, int len) { int err, cmt_retries = 0, nospc_retries = 0; ubifs_assert(len <= c->dark_wm); again: down_read(&c->commit_sem); err = reserve_space(c, jhead, len); if (!err) return 0; up_read(&c->commit_sem); if (err == -ENOSPC) { /* * GC could not make any progress. We should try to commit * once because it could make some dirty space and GC would * make progress, so make the error -EAGAIN so that the below * will commit and re-try. */ if (nospc_retries++ < 2) { dbg_jrn("no space, retry"); err = -EAGAIN; } /* * This means that the budgeting is incorrect. We always have * to be able to write to the media, because all operations are * budgeted. Deletions are not budgeted, though, but we reserve * an extra LEB for them. */ } if (err != -EAGAIN) goto out; /* * -EAGAIN means that the journal is full or too large, or the above * code wants to do one commit. Do this and re-try. */ if (cmt_retries > 128) { /* * This should not happen unless the journal size limitations * are too tough. */ ubifs_err("stuck in space allocation"); err = -ENOSPC; goto out; } else if (cmt_retries > 32) ubifs_warn("too many space allocation re-tries (%d)", cmt_retries); dbg_jrn("-EAGAIN, commit and retry (retried %d times)", cmt_retries); cmt_retries += 1; err = ubifs_run_commit(c); if (err) return err; goto again; out: ubifs_err("cannot reserve %d bytes in jhead %d, error %d", len, jhead, err); if (err == -ENOSPC) { /* This are some budgeting problems, print useful information */ down_write(&c->commit_sem); spin_lock(&c->space_lock); dbg_dump_stack(); dbg_dump_budg(c); spin_unlock(&c->space_lock); dbg_dump_lprops(c); cmt_retries = dbg_check_lprops(c); up_write(&c->commit_sem); } return err; }
/** * ubifs_new_inode - allocate new UBIFS inode object. * @c: UBIFS file-system description object * @dir: parent directory inode * @mode: inode mode flags * * This function finds an unused inode number, allocates new inode and * initializes it. Returns new inode in case of success and an error code in * case of failure. */ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, umode_t mode) { struct inode *inode; struct ubifs_inode *ui; inode = new_inode(c->vfs_sb); ui = ubifs_inode(inode); if (!inode) return ERR_PTR(-ENOMEM); /* * Set 'S_NOCMTIME' to prevent VFS form updating [mc]time of inodes and * marking them dirty in file write path (see 'file_update_time()'). * UBIFS has to fully control "clean <-> dirty" transitions of inodes * to make budgeting work. */ inode->i_flags |= S_NOCMTIME; inode_init_owner(inode, dir, mode); inode->i_mtime = inode->i_atime = inode->i_ctime = ubifs_current_time(inode); inode->i_mapping->nrpages = 0; switch (mode & S_IFMT) { case S_IFREG: inode->i_mapping->a_ops = &ubifs_file_address_operations; inode->i_op = &ubifs_file_inode_operations; inode->i_fop = &ubifs_file_operations; break; case S_IFDIR: inode->i_op = &ubifs_dir_inode_operations; inode->i_fop = &ubifs_dir_operations; inode->i_size = ui->ui_size = UBIFS_INO_NODE_SZ; break; case S_IFLNK: inode->i_op = &ubifs_symlink_inode_operations; break; case S_IFSOCK: case S_IFIFO: case S_IFBLK: case S_IFCHR: inode->i_op = &ubifs_file_inode_operations; break; default: BUG(); } ui->flags = inherit_flags(dir, mode); ubifs_set_inode_flags(inode); if (S_ISREG(mode)) ui->compr_type = c->default_compr; else ui->compr_type = UBIFS_COMPR_NONE; ui->synced_i_size = 0; spin_lock(&c->cnt_lock); /* Inode number overflow is currently not supported */ if (c->highest_inum >= INUM_WARN_WATERMARK) { if (c->highest_inum >= INUM_WATERMARK) { spin_unlock(&c->cnt_lock); ubifs_err(c, "out of inode numbers"); make_bad_inode(inode); iput(inode); return ERR_PTR(-EINVAL); } ubifs_warn(c, "running out of inode numbers (current %lu, max %u)", (unsigned long)c->highest_inum, INUM_WATERMARK); } inode->i_ino = ++c->highest_inum; /* * The creation sequence number remains with this inode for its * lifetime. All nodes for this inode have a greater sequence number, * and so it is possible to distinguish obsolete nodes belonging to a * previous incarnation of the same inode number - for example, for the * purpose of rebuilding the index. */ ui->creat_sqnum = ++c->max_sqnum; spin_unlock(&c->cnt_lock); return inode; }
/** * init_constants_early - initialize UBIFS constants. * @c: UBIFS file-system description object * * This function initialize UBIFS constants which do not need the superblock to * be read. It also checks that the UBI volume satisfies basic UBIFS * requirements. Returns zero in case of success and a negative error code in * case of failure. */ static int init_constants_early(struct ubifs_info *c) { if (c->vi.corrupted) { ubifs_warn("UBI volume is corrupted - read-only mode"); c->ro_media = 1; } if (c->di.ro_mode) { ubifs_msg("read-only UBI device"); c->ro_media = 1; } if (c->vi.vol_type == UBI_STATIC_VOLUME) { ubifs_msg("static UBI volume - read-only mode"); c->ro_media = 1; } c->leb_cnt = c->vi.size; c->leb_size = c->vi.usable_leb_size; c->half_leb_size = c->leb_size / 2; c->min_io_size = c->di.min_io_size; c->min_io_shift = fls(c->min_io_size) - 1; if (c->leb_size < UBIFS_MIN_LEB_SZ) { ubifs_err("too small LEBs (%d bytes), min. is %d bytes", c->leb_size, UBIFS_MIN_LEB_SZ); return -EINVAL; } if (c->leb_cnt < UBIFS_MIN_LEB_CNT) { ubifs_err("too few LEBs (%d), min. is %d", c->leb_cnt, UBIFS_MIN_LEB_CNT); return -EINVAL; } if (!is_power_of_2(c->min_io_size)) { ubifs_err("bad min. I/O size %d", c->min_io_size); return -EINVAL; } /* * UBIFS aligns all node to 8-byte boundary, so to make function in * io.c simpler, assume minimum I/O unit size to be 8 bytes if it is * less than 8. */ if (c->min_io_size < 8) { c->min_io_size = 8; c->min_io_shift = 3; } c->ref_node_alsz = ALIGN(UBIFS_REF_NODE_SZ, c->min_io_size); c->mst_node_alsz = ALIGN(UBIFS_MST_NODE_SZ, c->min_io_size); /* * Initialize node length ranges which are mostly needed for node * length validation. */ c->ranges[UBIFS_PAD_NODE].len = UBIFS_PAD_NODE_SZ; c->ranges[UBIFS_SB_NODE].len = UBIFS_SB_NODE_SZ; c->ranges[UBIFS_MST_NODE].len = UBIFS_MST_NODE_SZ; c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ; c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ; c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ; c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ; c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ; c->ranges[UBIFS_ORPH_NODE].min_len = UBIFS_ORPH_NODE_SZ + sizeof(__le64); c->ranges[UBIFS_ORPH_NODE].max_len = c->leb_size; c->ranges[UBIFS_DENT_NODE].min_len = UBIFS_DENT_NODE_SZ; c->ranges[UBIFS_DENT_NODE].max_len = UBIFS_MAX_DENT_NODE_SZ; c->ranges[UBIFS_XENT_NODE].min_len = UBIFS_XENT_NODE_SZ; c->ranges[UBIFS_XENT_NODE].max_len = UBIFS_MAX_XENT_NODE_SZ; c->ranges[UBIFS_DATA_NODE].min_len = UBIFS_DATA_NODE_SZ; c->ranges[UBIFS_DATA_NODE].max_len = UBIFS_MAX_DATA_NODE_SZ; /* * Minimum indexing node size is amended later when superblock is * read and the key length is known. */ c->ranges[UBIFS_IDX_NODE].min_len = UBIFS_IDX_NODE_SZ + UBIFS_BRANCH_SZ; /* * Maximum indexing node size is amended later when superblock is * read and the fanout is known. */ c->ranges[UBIFS_IDX_NODE].max_len = INT_MAX; /* * Initialize dead and dark LEB space watermarks. See gc.c for comments * about these values. */ c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size); c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size); /* * Calculate how many bytes would be wasted at the end of LEB if it was * fully filled with data nodes of maximum size. This is used in * calculations when reporting free space. */ c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ; return 0; }
static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { int err; union ubifs_key key; struct inode *inode = NULL; struct ubifs_dent_node *dent; struct ubifs_info *c = dir->i_sb->s_fs_info; struct fscrypt_name nm; dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino); if (ubifs_crypt_is_encrypted(dir)) { err = fscrypt_get_encryption_info(dir); /* * DCACHE_ENCRYPTED_WITH_KEY is set if the dentry is * created while the directory was encrypted and we * have access to the key. */ if (fscrypt_has_encryption_key(dir)) fscrypt_set_encrypted_dentry(dentry); fscrypt_set_d_op(dentry); if (err && err != -ENOKEY) return ERR_PTR(err); } err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); if (err) return ERR_PTR(err); if (fname_len(&nm) > UBIFS_MAX_NLEN) { err = -ENAMETOOLONG; goto out_fname; } dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); if (!dent) { err = -ENOMEM; goto out_fname; } if (nm.hash) { ubifs_assert(fname_len(&nm) == 0); ubifs_assert(fname_name(&nm) == NULL); dent_key_init_hash(c, &key, dir->i_ino, nm.hash); err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash); } else { dent_key_init(c, &key, dir->i_ino, &nm); err = ubifs_tnc_lookup_nm(c, &key, dent, &nm); } if (err) { if (err == -ENOENT) { dbg_gen("not found"); goto done; } goto out_dent; } if (dbg_check_name(c, dent, &nm)) { err = -EINVAL; goto out_dent; } inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum)); if (IS_ERR(inode)) { /* * This should not happen. Probably the file-system needs * checking. */ err = PTR_ERR(inode); ubifs_err(c, "dead directory entry '%pd', error %d", dentry, err); ubifs_ro_mode(c, err); goto out_dent; } if (ubifs_crypt_is_encrypted(dir) && (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && !fscrypt_has_permitted_context(dir, inode)) { ubifs_warn(c, "Inconsistent encryption contexts: %lu/%lu", dir->i_ino, inode->i_ino); err = -EPERM; goto out_inode; } done: kfree(dent); fscrypt_free_filename(&nm); /* * Note, d_splice_alias() would be required instead if we supported * NFS. */ d_add(dentry, inode); return NULL; out_inode: iput(inode); out_dent: kfree(dent); out_fname: fscrypt_free_filename(&nm); return ERR_PTR(err); }