|
Packit Service |
360c39 |
#include "clusterautoconfig.h"
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
#include <stdio.h>
|
|
Packit Service |
360c39 |
#include <stdlib.h>
|
|
Packit Service |
360c39 |
#include <string.h>
|
|
Packit Service |
360c39 |
#include <stdint.h>
|
|
Packit Service |
360c39 |
#include <inttypes.h>
|
|
Packit Service |
360c39 |
#include <sys/types.h>
|
|
Packit Service |
360c39 |
#include <sys/stat.h>
|
|
Packit Service |
360c39 |
#include <fcntl.h>
|
|
Packit Service |
360c39 |
#include <unistd.h>
|
|
Packit Service |
360c39 |
#include <errno.h>
|
|
Packit Service |
360c39 |
#include <linux/types.h>
|
|
Packit Service |
360c39 |
#include <sys/time.h>
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
#include "libgfs2.h"
|
|
Packit Service |
360c39 |
#include "config.h"
|
|
Packit Service |
360c39 |
#include "crc32c.h"
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
#ifdef GFS2_HAS_UUID
|
|
Packit Service |
360c39 |
#include <uuid.h>
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_master(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inum inum;
|
|
Packit Service |
360c39 |
uint64_t bn;
|
|
Packit Service |
360c39 |
struct gfs2_buffer_head *bh = NULL;
|
|
Packit Service |
360c39 |
int err = lgfs2_dinode_alloc(sdp, 1, &bn);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (err != 0)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inum.no_formal_ino = sdp->md.next_inum++;
|
|
Packit Service |
360c39 |
inum.no_addr = bn;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
err = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
|
|
Packit Service |
360c39 |
if (err != 0)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sdp->master_dir = lgfs2_inode_get(sdp, bh);
|
|
Packit Service |
360c39 |
if (sdp->master_dir == NULL)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nMaster dir:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&sdp->master_dir->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
sdp->master_dir->bh_owned = 1;
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* Initialise a gfs2_sb structure with sensible defaults.
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
void lgfs2_sb_init(struct gfs2_sb *sb, unsigned bsize)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
memset(sb, 0, sizeof(struct gfs2_sb));
|
|
Packit Service |
360c39 |
sb->sb_header.mh_magic = GFS2_MAGIC;
|
|
Packit Service |
360c39 |
sb->sb_header.mh_type = GFS2_METATYPE_SB;
|
|
Packit Service |
360c39 |
sb->sb_header.mh_format = GFS2_FORMAT_SB;
|
|
Packit Service |
360c39 |
sb->sb_fs_format = GFS2_FORMAT_FS;
|
|
Packit Service |
360c39 |
sb->sb_multihost_format = GFS2_FORMAT_MULTI;
|
|
Packit Service |
360c39 |
sb->sb_bsize = bsize;
|
|
Packit Service |
360c39 |
sb->sb_bsize_shift = ffs(bsize) - 1;
|
|
Packit Service |
360c39 |
#ifdef GFS2_HAS_UUID
|
|
Packit Service |
360c39 |
uuid_generate(sb->sb_uuid);
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int lgfs2_sb_write(const struct gfs2_sb *sb, int fd, const unsigned bsize)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
int i, err = -1;
|
|
Packit Service |
360c39 |
struct iovec *iov;
|
|
Packit Service |
360c39 |
const size_t sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / bsize;
|
|
Packit Service |
360c39 |
const size_t len = sb_addr + 1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/* We only need 2 blocks: one for zeroing and a second for the superblock */
|
|
Packit Service |
360c39 |
char *buf = calloc(2, bsize);
|
|
Packit Service |
360c39 |
if (buf == NULL)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
iov = malloc(len * sizeof(*iov));
|
|
Packit Service |
360c39 |
if (iov == NULL)
|
|
Packit Service |
360c39 |
goto out_buf;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for (i = 0; i < len; i++) {
|
|
Packit Service |
360c39 |
iov[i].iov_base = buf;
|
|
Packit Service |
360c39 |
iov[i].iov_len = bsize;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
gfs2_sb_out(sb, buf + bsize);
|
|
Packit Service |
360c39 |
iov[sb_addr].iov_base = buf + bsize;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (pwritev(fd, iov, len, 0) < (len * bsize))
|
|
Packit Service |
360c39 |
goto out_iov;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
err = 0;
|
|
Packit Service |
360c39 |
out_iov:
|
|
Packit Service |
360c39 |
free(iov);
|
|
Packit Service |
360c39 |
out_buf:
|
|
Packit Service |
360c39 |
free(buf);
|
|
Packit Service |
360c39 |
return err;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
uint32_t lgfs2_log_header_hash(char *buf)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
/* lh_hash only CRCs the fields in the old lh, which ends where lh_crc is now */
|
|
Packit Service |
360c39 |
const off_t v1_end = offsetof(struct gfs2_log_header, lh_hash) + 4;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
return gfs2_disk_hash(buf, v1_end);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
uint32_t lgfs2_log_header_crc(char *buf, unsigned bsize)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
#ifdef GFS2_HAS_LH_V2
|
|
Packit Service |
360c39 |
/* lh_crc CRCs the rest of the block starting after lh_crc */
|
|
Packit Service |
360c39 |
const off_t v1_end = offsetof(struct gfs2_log_header, lh_hash) + 4;
|
|
Packit Service |
360c39 |
const unsigned char *lb = (const unsigned char *)buf;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
return crc32c(~0, lb + v1_end + 4, bsize - v1_end - 4);
|
|
Packit Service |
360c39 |
#else
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* Intialise and write the data blocks for a new journal as a contiguous
|
|
Packit Service |
360c39 |
* extent. The indirect blocks pointing to these data blocks should have been
|
|
Packit Service |
360c39 |
* written separately using lgfs2_write_filemeta() and the extent should have
|
|
Packit Service |
360c39 |
* been allocated using lgfs2_file_alloc().
|
|
Packit Service |
360c39 |
* ip: The journal's inode
|
|
Packit Service |
360c39 |
* Returns 0 on success or -1 with errno set on error.
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
int lgfs2_write_journal_data(struct gfs2_inode *ip)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_log_header lh = {
|
|
Packit Service |
360c39 |
.lh_header.mh_magic = GFS2_MAGIC,
|
|
Packit Service |
360c39 |
.lh_header.mh_type = GFS2_METATYPE_LH,
|
|
Packit Service |
360c39 |
.lh_header.mh_format = GFS2_FORMAT_LH,
|
|
Packit Service |
360c39 |
.lh_tail = 0,
|
|
Packit Service |
360c39 |
.lh_blkno = 0,
|
|
Packit Service |
360c39 |
.lh_hash = 0,
|
|
Packit Service |
360c39 |
#ifdef GFS2_HAS_LH_V2
|
|
Packit Service |
360c39 |
.lh_flags = GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_USERSPACE,
|
|
Packit Service |
360c39 |
.lh_crc = 0,
|
|
Packit Service |
360c39 |
.lh_nsec = 0,
|
|
Packit Service |
360c39 |
.lh_sec = 0,
|
|
Packit Service |
360c39 |
.lh_jinode = ip->i_di.di_num.no_addr,
|
|
Packit Service |
360c39 |
.lh_statfs_addr = 0,
|
|
Packit Service |
360c39 |
.lh_quota_addr = 0,
|
|
Packit Service |
360c39 |
.lh_local_total = 0,
|
|
Packit Service |
360c39 |
.lh_local_free = 0,
|
|
Packit Service |
360c39 |
.lh_local_dinodes = 0,
|
|
Packit Service |
360c39 |
#else
|
|
Packit Service |
360c39 |
.lh_flags = GFS2_LOG_HEAD_UNMOUNT,
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
};
|
|
Packit Service |
360c39 |
struct gfs2_buffer_head *bh;
|
|
Packit Service |
360c39 |
struct gfs2_sbd *sdp = ip->i_sbd;
|
|
Packit Service |
360c39 |
unsigned blocks = (ip->i_di.di_size + sdp->bsize - 1) / sdp->bsize;
|
|
Packit Service |
360c39 |
uint64_t jext0 = ip->i_di.di_num.no_addr + ip->i_di.di_blocks - blocks;
|
|
Packit Service |
360c39 |
uint64_t seq = ((blocks) * (random() / (RAND_MAX + 1.0)));
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
bh = bget(sdp, jext0);
|
|
Packit Service |
360c39 |
if (bh == NULL)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
crc32c_optimization_init();
|
|
Packit Service |
360c39 |
do {
|
|
Packit Service |
360c39 |
struct gfs2_log_header *buflh = (struct gfs2_log_header *)bh->b_data;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
lh.lh_sequence = seq;
|
|
Packit Service |
360c39 |
lh.lh_blkno = bh->b_blocknr - jext0;
|
|
Packit Service |
360c39 |
gfs2_log_header_out(&lh, bh->b_data);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
buflh->lh_hash = cpu_to_be32(lgfs2_log_header_hash(bh->b_data));
|
|
Packit Service |
360c39 |
#ifdef GFS2_HAS_LH_V2
|
|
Packit Service |
360c39 |
buflh->lh_addr = cpu_to_be64(bh->b_blocknr);
|
|
Packit Service |
360c39 |
buflh->lh_crc = cpu_to_be32(lgfs2_log_header_crc(bh->b_data, sdp->bsize));
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (bwrite(bh)) {
|
|
Packit Service |
360c39 |
free(bh);
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (++seq == blocks)
|
|
Packit Service |
360c39 |
seq = 0;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
} while (++bh->b_blocknr < jext0 + blocks);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
free(bh);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int write_journal(struct gfs2_inode *jnl, unsigned bsize, unsigned int blocks)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_log_header lh;
|
|
Packit Service |
360c39 |
unsigned int x;
|
|
Packit Service |
360c39 |
uint64_t seq = ((blocks) * (random() / (RAND_MAX + 1.0)));
|
|
Packit Service |
360c39 |
uint32_t hash;
|
|
Packit Service |
360c39 |
unsigned int height;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/* Build the height up so our journal blocks will be contiguous and */
|
|
Packit Service |
360c39 |
/* not broken up by indirect block pages. */
|
|
Packit Service |
360c39 |
height = calc_tree_height(jnl, (blocks + 1) * bsize);
|
|
Packit Service |
360c39 |
build_height(jnl, height);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
memset(&lh, 0, sizeof(struct gfs2_log_header));
|
|
Packit Service |
360c39 |
lh.lh_header.mh_magic = GFS2_MAGIC;
|
|
Packit Service |
360c39 |
lh.lh_header.mh_type = GFS2_METATYPE_LH;
|
|
Packit Service |
360c39 |
lh.lh_header.mh_format = GFS2_FORMAT_LH;
|
|
Packit Service |
360c39 |
lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT;
|
|
Packit Service |
360c39 |
#ifdef GFS2_HAS_LH_V2
|
|
Packit Service |
360c39 |
lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE;
|
|
Packit Service |
360c39 |
lh.lh_jinode = jnl->i_di.di_num.no_addr;
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
for (x = 0; x < blocks; x++) {
|
|
Packit Service |
360c39 |
struct gfs2_buffer_head *bh = get_file_buf(jnl, x, TRUE);
|
|
Packit Service |
360c39 |
if (!bh)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
bmodified(bh);
|
|
Packit Service |
360c39 |
brelse(bh);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
crc32c_optimization_init();
|
|
Packit Service |
360c39 |
for (x = 0; x < blocks; x++) {
|
|
Packit Service |
360c39 |
struct gfs2_buffer_head *bh = get_file_buf(jnl, x, FALSE);
|
|
Packit Service |
360c39 |
if (!bh)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
memset(bh->b_data, 0, bsize);
|
|
Packit Service |
360c39 |
lh.lh_sequence = seq;
|
|
Packit Service |
360c39 |
lh.lh_blkno = x;
|
|
Packit Service |
360c39 |
gfs2_log_header_out(&lh, bh->b_data);
|
|
Packit Service |
360c39 |
hash = lgfs2_log_header_hash(bh->b_data);
|
|
Packit Service |
360c39 |
((struct gfs2_log_header *)bh->b_data)->lh_hash = cpu_to_be32(hash);
|
|
Packit Service |
360c39 |
#ifdef GFS2_HAS_LH_V2
|
|
Packit Service |
360c39 |
((struct gfs2_log_header *)bh->b_data)->lh_addr = cpu_to_be64(bh->b_blocknr);
|
|
Packit Service |
360c39 |
hash = lgfs2_log_header_crc(bh->b_data, bsize);
|
|
Packit Service |
360c39 |
((struct gfs2_log_header *)bh->b_data)->lh_crc = cpu_to_be32(hash);
|
|
Packit Service |
360c39 |
#endif
|
|
Packit Service |
360c39 |
bmodified(bh);
|
|
Packit Service |
360c39 |
brelse(bh);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (++seq == blocks)
|
|
Packit Service |
360c39 |
seq = 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_journal(struct gfs2_sbd *sdp, int j, struct gfs2_inode *jindex)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
char name[256];
|
|
Packit Service |
360c39 |
int ret;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sprintf(name, "journal%u", j);
|
|
Packit Service |
360c39 |
sdp->md.journal[j] = createi(jindex, name, S_IFREG | 0600,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM);
|
|
Packit Service |
360c39 |
if (sdp->md.journal[j] == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
ret = write_journal(sdp->md.journal[j], sdp->bsize,
|
|
Packit Service |
360c39 |
sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
|
|
Packit Service |
360c39 |
return ret;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
/**
|
|
Packit Service |
360c39 |
* Write a jindex file given a list of journal inums.
|
|
Packit Service |
360c39 |
* master: Inode of the master directory
|
|
Packit Service |
360c39 |
* jnls: List of inum structures relating to previously created journals.
|
|
Packit Service |
360c39 |
* nmemb: The number of entries in the list (number of journals).
|
|
Packit Service |
360c39 |
* Returns 0 on success or non-zero on error with errno set.
|
|
Packit Service |
360c39 |
*/
|
|
Packit Service |
360c39 |
int lgfs2_build_jindex(struct gfs2_inode *master, struct gfs2_inum *jnls, size_t nmemb)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
char fname[GFS2_FNAMESIZE + 1];
|
|
Packit Service |
360c39 |
struct gfs2_inode *jindex;
|
|
Packit Service |
360c39 |
unsigned j;
|
|
Packit Service |
360c39 |
int ret;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (nmemb == 0 || jnls == NULL) {
|
|
Packit Service |
360c39 |
errno = EINVAL;
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
jindex = createi(master, "jindex", S_IFDIR | 0700, GFS2_DIF_SYSTEM);
|
|
Packit Service |
360c39 |
if (jindex == NULL)
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
fname[GFS2_FNAMESIZE] = '\0';
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for (j = 0; j < nmemb; j++) {
|
|
Packit Service |
360c39 |
snprintf(fname, GFS2_FNAMESIZE, "journal%u", j);
|
|
Packit Service |
360c39 |
ret = dir_add(jindex, fname, strlen(fname), &jnls[j], IF2DT(S_IFREG | 0600));
|
|
Packit Service |
360c39 |
if (ret) {
|
|
Packit Service |
360c39 |
inode_put(&jindex);
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nJindex:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&jindex->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&jindex);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_jindex(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *jindex;
|
|
Packit Service |
360c39 |
unsigned int j;
|
|
Packit Service |
360c39 |
int ret;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
jindex = createi(sdp->master_dir, "jindex", S_IFDIR | 0700,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM);
|
|
Packit Service |
360c39 |
if (jindex == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
sdp->md.journal = malloc(sdp->md.journals *
|
|
Packit Service |
360c39 |
sizeof(struct gfs2_inode *));
|
|
Packit Service |
360c39 |
for (j = 0; j < sdp->md.journals; j++) {
|
|
Packit Service |
360c39 |
ret = build_journal(sdp, j, jindex);
|
|
Packit Service |
360c39 |
if (ret)
|
|
Packit Service |
360c39 |
return ret;
|
|
Packit Service |
360c39 |
inode_put(&sdp->md.journal[j]);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nJindex:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&jindex->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
free(sdp->md.journal);
|
|
Packit Service |
360c39 |
inode_put(&jindex);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_inum_range(struct gfs2_inode *per_node, unsigned int j)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
char name[256];
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sprintf(name, "inum_range%u", j);
|
|
Packit Service |
360c39 |
ip = createi(per_node, name, S_IFREG | 0600,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
|
|
Packit Service |
360c39 |
if (ip == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
ip->i_di.di_size = sizeof(struct gfs2_inum_range);
|
|
Packit Service |
360c39 |
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
|
|
Packit Service |
360c39 |
bmodified(ip->i_bh);
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nInum Range %u:\n", j);
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&ip->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&ip);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_statfs_change(struct gfs2_inode *per_node, unsigned int j)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
char name[256];
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sprintf(name, "statfs_change%u", j);
|
|
Packit Service |
360c39 |
ip = createi(per_node, name, S_IFREG | 0600,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
|
|
Packit Service |
360c39 |
if (ip == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
ip->i_di.di_size = sizeof(struct gfs2_statfs_change);
|
|
Packit Service |
360c39 |
gfs2_dinode_out(&ip->i_di, ip->i_bh->b_data);
|
|
Packit Service |
360c39 |
bmodified(ip->i_bh);
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nStatFS Change %u:\n", j);
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&ip->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&ip);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_quota_change(struct gfs2_inode *per_node, unsigned int j)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_sbd *sdp = per_node->i_sbd;
|
|
Packit Service |
360c39 |
struct gfs2_meta_header mh;
|
|
Packit Service |
360c39 |
char name[256];
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip;
|
|
Packit Service |
360c39 |
unsigned int blocks = sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift);
|
|
Packit Service |
360c39 |
unsigned int x;
|
|
Packit Service |
360c39 |
unsigned int hgt;
|
|
Packit Service |
360c39 |
struct gfs2_buffer_head *bh;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
memset(&mh, 0, sizeof(struct gfs2_meta_header));
|
|
Packit Service |
360c39 |
mh.mh_magic = GFS2_MAGIC;
|
|
Packit Service |
360c39 |
mh.mh_type = GFS2_METATYPE_QC;
|
|
Packit Service |
360c39 |
mh.mh_format = GFS2_FORMAT_QC;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sprintf(name, "quota_change%u", j);
|
|
Packit Service |
360c39 |
ip = createi(per_node, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
|
|
Packit Service |
360c39 |
if (ip == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
hgt = calc_tree_height(ip, (blocks + 1) * sdp->bsize);
|
|
Packit Service |
360c39 |
build_height(ip, hgt);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for (x = 0; x < blocks; x++) {
|
|
Packit Service |
360c39 |
bh = get_file_buf(ip, x, FALSE);
|
|
Packit Service |
360c39 |
if (!bh)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
memset(bh->b_data, 0, sdp->bsize);
|
|
Packit Service |
360c39 |
gfs2_meta_header_out(&mh, bh->b_data);
|
|
Packit Service |
360c39 |
bmodified(bh);
|
|
Packit Service |
360c39 |
brelse(bh);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nQuota Change %u:\n", j);
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&ip->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&ip);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_per_node(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *per_node;
|
|
Packit Service |
360c39 |
unsigned int j;
|
|
Packit Service |
360c39 |
int err;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
per_node = createi(sdp->master_dir, "per_node", S_IFDIR | 0700,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM);
|
|
Packit Service |
360c39 |
if (per_node == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for (j = 0; j < sdp->md.journals; j++) {
|
|
Packit Service |
360c39 |
err = build_inum_range(per_node, j);
|
|
Packit Service |
360c39 |
if (err) {
|
|
Packit Service |
360c39 |
return err;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
err = build_statfs_change(per_node, j);
|
|
Packit Service |
360c39 |
if (err) {
|
|
Packit Service |
360c39 |
return err;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
err = build_quota_change(per_node, j);
|
|
Packit Service |
360c39 |
if (err) {
|
|
Packit Service |
360c39 |
return err;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nper_node:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&per_node->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&per_node);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_inum(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
ip = createi(sdp->master_dir, "inum", S_IFREG | 0600,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
|
|
Packit Service |
360c39 |
if (ip == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nInum Inode:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&ip->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&ip);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_statfs(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
ip = createi(sdp->master_dir, "statfs", S_IFREG | 0600,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
|
|
Packit Service |
360c39 |
if (ip == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nStatFS Inode:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&ip->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&ip);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_rindex(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip;
|
|
Packit Service |
360c39 |
struct osi_node *n, *next = NULL;
|
|
Packit Service |
360c39 |
struct rgrp_tree *rl;
|
|
Packit Service |
360c39 |
char buf[sizeof(struct gfs2_rindex)];
|
|
Packit Service |
360c39 |
int count;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
ip = createi(sdp->master_dir, "rindex", S_IFREG | 0600,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
|
|
Packit Service |
360c39 |
if (ip == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
ip->i_di.di_payload_format = GFS2_FORMAT_RI;
|
|
Packit Service |
360c39 |
bmodified(ip->i_bh);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for (n = osi_first(&sdp->rgtree); n; n = next) {
|
|
Packit Service |
360c39 |
next = osi_next(n);
|
|
Packit Service |
360c39 |
rl = (struct rgrp_tree *)n;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
gfs2_rindex_out(&rl->ri, buf);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
count = gfs2_writei(ip, buf, ip->i_di.di_size,
|
|
Packit Service |
360c39 |
sizeof(struct gfs2_rindex));
|
|
Packit Service |
360c39 |
if (count != sizeof(struct gfs2_rindex))
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
memset(buf, 0, sizeof(struct gfs2_rindex));
|
|
Packit Service |
360c39 |
count = __gfs2_writei(ip, buf, ip->i_di.di_size,
|
|
Packit Service |
360c39 |
sizeof(struct gfs2_rindex), 0);
|
|
Packit Service |
360c39 |
if (count != sizeof(struct gfs2_rindex))
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nResource Index:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&ip->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&ip);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_quota(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip;
|
|
Packit Service |
360c39 |
struct gfs2_quota qu;
|
|
Packit Service |
360c39 |
char buf[sizeof(struct gfs2_quota)];
|
|
Packit Service |
360c39 |
int count;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
ip = createi(sdp->master_dir, "quota", S_IFREG | 0600,
|
|
Packit Service |
360c39 |
GFS2_DIF_SYSTEM | GFS2_DIF_JDATA);
|
|
Packit Service |
360c39 |
if (ip == NULL) {
|
|
Packit Service |
360c39 |
return errno;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
ip->i_di.di_payload_format = GFS2_FORMAT_QU;
|
|
Packit Service |
360c39 |
bmodified(ip->i_bh);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
memset(&qu, 0, sizeof(struct gfs2_quota));
|
|
Packit Service |
360c39 |
qu.qu_value = 1;
|
|
Packit Service |
360c39 |
gfs2_quota_out(&qu, buf);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
count = gfs2_writei(ip, buf, ip->i_di.di_size, sizeof(struct gfs2_quota));
|
|
Packit Service |
360c39 |
if (count != sizeof(struct gfs2_quota))
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
count = gfs2_writei(ip, buf, ip->i_di.di_size, sizeof(struct gfs2_quota));
|
|
Packit Service |
360c39 |
if (count != sizeof(struct gfs2_quota))
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nRoot quota:\n");
|
|
Packit Service |
360c39 |
gfs2_quota_print(&qu);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inode_put(&ip);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int build_root(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inum inum;
|
|
Packit Service |
360c39 |
uint64_t bn;
|
|
Packit Service |
360c39 |
struct gfs2_buffer_head *bh = NULL;
|
|
Packit Service |
360c39 |
int err = lgfs2_dinode_alloc(sdp, 1, &bn);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (err != 0)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
inum.no_formal_ino = sdp->md.next_inum++;
|
|
Packit Service |
360c39 |
inum.no_addr = bn;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
err = init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, 0, &inum);
|
|
Packit Service |
360c39 |
if (err != 0)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sdp->md.rooti = lgfs2_inode_get(sdp, bh);
|
|
Packit Service |
360c39 |
if (sdp->md.rooti == NULL)
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nRoot directory:\n");
|
|
Packit Service |
360c39 |
gfs2_dinode_print(&sdp->md.rooti->i_di);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
sdp->md.rooti->bh_owned = 1;
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int do_init_inum(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip = sdp->md.inum;
|
|
Packit Service |
360c39 |
uint64_t buf;
|
|
Packit Service |
360c39 |
int count;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
buf = cpu_to_be64(sdp->md.next_inum);
|
|
Packit Service |
360c39 |
count = gfs2_writei(ip, &buf, 0, sizeof(uint64_t));
|
|
Packit Service |
360c39 |
if (count != sizeof(uint64_t))
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug)
|
|
Packit Service |
360c39 |
printf("\nNext Inum: %"PRIu64"\n",
|
|
Packit Service |
360c39 |
sdp->md.next_inum);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int do_init_statfs(struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_inode *ip = sdp->md.statfs;
|
|
Packit Service |
360c39 |
struct gfs2_statfs_change sc;
|
|
Packit Service |
360c39 |
char buf[sizeof(struct gfs2_statfs_change)];
|
|
Packit Service |
360c39 |
int count;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sc.sc_total = sdp->blks_total;
|
|
Packit Service |
360c39 |
sc.sc_free = sdp->blks_total - sdp->blks_alloced;
|
|
Packit Service |
360c39 |
sc.sc_dinodes = sdp->dinodes_alloced;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
gfs2_statfs_change_out(&sc, buf);
|
|
Packit Service |
360c39 |
count = gfs2_writei(ip, buf, 0, sizeof(struct gfs2_statfs_change));
|
|
Packit Service |
360c39 |
if (count != sizeof(struct gfs2_statfs_change))
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (cfg_debug) {
|
|
Packit Service |
360c39 |
printf("\nStatfs:\n");
|
|
Packit Service |
360c39 |
gfs2_statfs_change_print(&sc);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
uint32_t check_magic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
|
|
Packit Service |
360c39 |
uint32_t check_type = ((struct gfs2_meta_header *)(bh->b_data))->mh_type;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
check_magic = be32_to_cpu(check_magic);
|
|
Packit Service |
360c39 |
check_type = be32_to_cpu(check_type);
|
|
Packit Service |
360c39 |
if((check_magic != GFS2_MAGIC) || (type && (check_type != type)))
|
|
Packit Service |
360c39 |
return -1;
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx, uint64_t *buf, uint8_t state)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
struct gfs2_bitmap *bi = &rgd->bits[idx];
|
|
Packit Service |
360c39 |
unsigned n = 0;
|
|
Packit Service |
360c39 |
uint32_t blk = 0;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
while(blk < (bi->bi_len * GFS2_NBBY)) {
|
|
Packit Service |
360c39 |
blk = gfs2_bitfit((uint8_t *)bi->bi_bh->b_data + bi->bi_offset,
|
|
Packit Service |
360c39 |
bi->bi_len, blk, state);
|
|
Packit Service |
360c39 |
if (blk == BFITNOENT)
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
buf[n++] = blk + (bi->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
|
|
Packit Service |
360c39 |
blk++;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
return n;
|
|
Packit Service |
360c39 |
}
|