Release 4.10 fs/gfs2/ops_fstype.c
/*
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License version 2.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/blkdev.h>
#include <linux/kthread.h>
#include <linux/export.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/gfs2_ondisk.h>
#include <linux/quotaops.h>
#include <linux/lockdep.h>
#include <linux/module.h>
#include "gfs2.h"
#include "incore.h"
#include "bmap.h"
#include "glock.h"
#include "glops.h"
#include "inode.h"
#include "recovery.h"
#include "rgrp.h"
#include "super.h"
#include "sys.h"
#include "util.h"
#include "log.h"
#include "quota.h"
#include "dir.h"
#include "meta_io.h"
#include "trace_gfs2.h"
#define DO 0
#define UNDO 1
/**
* gfs2_tune_init - Fill a gfs2_tune structure with default values
* @gt: tune
*
*/
static void gfs2_tune_init(struct gfs2_tune *gt)
{
spin_lock_init(>->gt_spin);
gt->gt_quota_warn_period = 10;
gt->gt_quota_scale_num = 1;
gt->gt_quota_scale_den = 1;
gt->gt_new_files_jdata = 0;
gt->gt_max_readahead = BIT(18);
gt->gt_complain_secs = 10;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 55 | 94.83% | 1 | 50.00% |
fabian frederick | fabian frederick | 3 | 5.17% | 1 | 50.00% |
| Total | 58 | 100.00% | 2 | 100.00% |
static struct gfs2_sbd *init_sbd(struct super_block *sb)
{
struct gfs2_sbd *sdp;
struct address_space *mapping;
sdp = kzalloc(sizeof(struct gfs2_sbd), GFP_KERNEL);
if (!sdp)
return NULL;
sb->s_fs_info = sdp;
sdp->sd_vfs = sb;
sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats);
if (!sdp->sd_lkstats) {
kfree(sdp);
return NULL;
}
set_bit(SDF_NOJOURNALID, &sdp->sd_flags);
gfs2_tune_init(&sdp->sd_tune);
init_waitqueue_head(&sdp->sd_glock_wait);
atomic_set(&sdp->sd_glock_disposal, 0);
init_completion(&sdp->sd_locking_init);
init_completion(&sdp->sd_wdack);
spin_lock_init(&sdp->sd_statfs_spin);
spin_lock_init(&sdp->sd_rindex_spin);
sdp->sd_rindex_tree.rb_node = NULL;
INIT_LIST_HEAD(&sdp->sd_jindex_list);
spin_lock_init(&sdp->sd_jindex_spin);
mutex_init(&sdp->sd_jindex_mutex);
init_completion(&sdp->sd_journal_ready);
INIT_LIST_HEAD(&sdp->sd_quota_list);
mutex_init(&sdp->sd_quota_mutex);
mutex_init(&sdp->sd_quota_sync_mutex);
init_waitqueue_head(&sdp->sd_quota_wait);
INIT_LIST_HEAD(&sdp->sd_trunc_list);
spin_lock_init(&sdp->sd_trunc_lock);
spin_lock_init(&sdp->sd_bitmap_lock);
mapping = &sdp->sd_aspace;
address_space_init_once(mapping);
mapping->a_ops = &gfs2_rgrp_aops;
mapping->host = sb->s_bdev->bd_inode;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_NOFS);
mapping->private_data = NULL;
mapping->writeback_index = 0;
spin_lock_init(&sdp->sd_log_lock);
atomic_set(&sdp->sd_log_pinned, 0);
INIT_LIST_HEAD(&sdp->sd_log_le_revoke);
INIT_LIST_HEAD(&sdp->sd_log_le_ordered);
spin_lock_init(&sdp->sd_ordered_lock);
init_waitqueue_head(&sdp->sd_log_waitq);
init_waitqueue_head(&sdp->sd_logd_waitq);
spin_lock_init(&sdp->sd_ail_lock);
INIT_LIST_HEAD(&sdp->sd_ail1_list);
INIT_LIST_HEAD(&sdp->sd_ail2_list);
init_rwsem(&sdp->sd_log_flush_lock);
atomic_set(&sdp->sd_log_in_flight, 0);
atomic_set(&sdp->sd_reserving_log, 0);
init_waitqueue_head(&sdp->sd_reserving_log_wait);
init_waitqueue_head(&sdp->sd_log_flush_wait);
atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
mutex_init(&sdp->sd_freeze_mutex);
return sdp;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 200 | 44.64% | 19 | 73.08% |
david teigland | david teigland | 169 | 37.72% | 1 | 3.85% |
benjamin marzinski | benjamin marzinski | 58 | 12.95% | 3 | 11.54% |
robert s. peterson | robert s. peterson | 13 | 2.90% | 2 | 7.69% |
dave chinner | dave chinner | 8 | 1.79% | 1 | 3.85% |
| Total | 448 | 100.00% | 26 | 100.00% |
/**
* gfs2_check_sb - Check superblock
* @sdp: the filesystem
* @sb: The superblock
* @silent: Don't print a message if the check fails
*
* Checks the version code of the FS is one that we understand how to
* read and that the sizes of the various on-disk structures have not
* changed.
*/
static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
{
struct gfs2_sb_host *sb = &sdp->sd_sb;
if (sb->sb_magic != GFS2_MAGIC ||
sb->sb_type != GFS2_METATYPE_SB) {
if (!silent)
pr_warn("not a GFS2 filesystem\n");
return -EINVAL;
}
/* If format numbers match exactly, we're done. */
if (sb->sb_fs_format == GFS2_FORMAT_FS &&
sb->sb_multihost_format == GFS2_FORMAT_MULTI)
return 0;
fs_warn(sdp, "Unknown on-disk format, unable to mount\n");
return -EINVAL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 55 | 66.27% | 3 | 50.00% |
david teigland | david teigland | 26 | 31.33% | 1 | 16.67% |
joe perches | joe perches | 1 | 1.20% | 1 | 16.67% |
fabian frederick | fabian frederick | 1 | 1.20% | 1 | 16.67% |
| Total | 83 | 100.00% | 6 | 100.00% |
static void end_bio_io_page(struct bio *bio)
{
struct page *page = bio->bi_private;
if (!bio->bi_error)
SetPageUptodate(page);
else
pr_warn("error %d reading superblock\n", bio->bi_error);
unlock_page(page);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 39 | 82.98% | 1 | 25.00% |
christoph hellwig | christoph hellwig | 6 | 12.77% | 1 | 25.00% |
joe perches | joe perches | 1 | 2.13% | 1 | 25.00% |
fabian frederick | fabian frederick | 1 | 2.13% | 1 | 25.00% |
| Total | 47 | 100.00% | 4 | 100.00% |
static void gfs2_sb_in(struct gfs2_sbd *sdp, const void *buf)
{
struct gfs2_sb_host *sb = &sdp->sd_sb;
struct super_block *s = sdp->sd_vfs;
const struct gfs2_sb *str = buf;
sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic);
sb->sb_type = be32_to_cpu(str->sb_header.mh_type);
sb->sb_format = be32_to_cpu(str->sb_header.mh_format);
sb->sb_fs_format = be32_to_cpu(str->sb_fs_format);
sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
sb->sb_bsize = be32_to_cpu(str->sb_bsize);
sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr);
sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino);
sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr);
sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino);
memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
memcpy(s->s_uuid, str->sb_uuid, 16);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 225 | 100.00% | 3 | 100.00% |
| Total | 225 | 100.00% | 3 | 100.00% |
/**
* gfs2_read_super - Read the gfs2 super block from disk
* @sdp: The GFS2 super block
* @sector: The location of the super block
* @error: The error code to return
*
* This uses the bio functions to read the super block from disk
* because we want to be 100% sure that we never read cached data.
* A super block is read twice only during each GFS2 mount and is
* never written to by the filesystem. The first time its read no
* locks are held, and the only details which are looked at are those
* relating to the locking protocol. Once locking is up and working,
* the sb is read again under the lock to establish the location of
* the master directory (contains pointers to journals etc) and the
* root directory.
*
* Returns: 0 on success or error
*/
static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector, int silent)
{
struct super_block *sb = sdp->sd_vfs;
struct gfs2_sb *p;
struct page *page;
struct bio *bio;
page = alloc_page(GFP_NOFS);
if (unlikely(!page))
return -ENOMEM;
ClearPageUptodate(page);
ClearPageDirty(page);
lock_page(page);
bio = bio_alloc(GFP_NOFS, 1);
bio->bi_iter.bi_sector = sector * (sb->s_blocksize >> 9);
bio->bi_bdev = sb->s_bdev;
bio_add_page(bio, page, PAGE_SIZE, 0);
bio->bi_end_io = end_bio_io_page;
bio->bi_private = page;
bio_set_op_attrs(bio, REQ_OP_READ, REQ_META);
submit_bio(bio);
wait_on_page_locked(page);
bio_put(bio);
if (!PageUptodate(page)) {
__free_page(page);
return -EIO;
}
p = kmap(page);
gfs2_sb_in(sdp, p);
kunmap(page);
__free_page(page);
return gfs2_check_sb(sdp, silent);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 194 | 94.17% | 3 | 42.86% |
michael christie | michael christie | 9 | 4.37% | 2 | 28.57% |
kent overstreet | kent overstreet | 2 | 0.97% | 1 | 14.29% |
christoph hellwig | christoph hellwig | 1 | 0.49% | 1 | 14.29% |
| Total | 206 | 100.00% | 7 | 100.00% |
/**
* gfs2_read_sb - Read super block
* @sdp: The GFS2 superblock
* @silent: Don't print message if mount fails
*
*/
static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent)
{
u32 hash_blocks, ind_blocks, leaf_blocks;
u32 tmp_blocks;
unsigned int x;
int error;
error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift, silent);
if (error) {
if (!silent)
fs_err(sdp, "can't read superblock\n");
return error;
}
sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
GFS2_BASIC_BLOCK_SHIFT;
sdp->sd_fsb2bb = BIT(sdp->sd_fsb2bb_shift);
sdp->sd_diptrs = (sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_dinode)) / sizeof(u64);
sdp->sd_inptrs = (sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_meta_header)) / sizeof(u64);
sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64);
sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_meta_header)) /
sizeof(struct gfs2_quota_change);
sdp->sd_blocks_per_bitmap = (sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_meta_header))
* GFS2_NBBY; /* not the rgrp bitmap, subsequent bitmaps only */
/* Compute maximum reservation required to add a entry to a directory */
hash_blocks = DIV_ROUND_UP(sizeof(u64) * BIT(GFS2_DIR_MAX_DEPTH),
sdp->sd_jbsize);
ind_blocks = 0;
for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) {
tmp_blocks = DIV_ROUND_UP(tmp_blocks, sdp->sd_inptrs);
ind_blocks += tmp_blocks;
}
leaf_blocks = 2 + GFS2_DIR_MAX_DEPTH;
sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks;
sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_dinode);
sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs;
for (x = 2;; x++) {
u64 space, d;
u32 m;
space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs;
d = space;
m = do_div(d, sdp->sd_inptrs);
if (d != sdp->sd_heightsize[x - 1] || m)
break;
sdp->sd_heightsize[x] = space;
}
sdp->sd_max_height = x;
sdp->sd_heightsize[x] = ~0;
gfs2_assert(sdp, sdp->sd_max_height <= GFS2_MAX_META_HEIGHT);
sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_dinode);
sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs;
for (x = 2;; x++) {
u64 space, d;
u32 m;
space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs;
d = space;
m = do_div(d, sdp->sd_inptrs);
if (d != sdp->sd_jheightsize[x - 1] || m)
break;
sdp->sd_jheightsize[x] = space;
}
sdp->sd_max_jheight = x;
sdp->sd_jheightsize[x] = ~0;
gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT);
sdp->sd_max_dents_per_leaf = (sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_leaf)) /
GFS2_MIN_DIRENT_SIZE;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 554 | 92.18% | 2 | 40.00% |
robert s. peterson | robert s. peterson | 21 | 3.49% | 1 | 20.00% |
benjamin marzinski | benjamin marzinski | 20 | 3.33% | 1 | 20.00% |
fabian frederick | fabian frederick | 6 | 1.00% | 1 | 20.00% |
| Total | 601 | 100.00% | 5 | 100.00% |
static int init_names(struct gfs2_sbd *sdp, int silent)
{
char *proto, *table;
int error = 0;
proto = sdp->sd_args.ar_lockproto;
table = sdp->sd_args.ar_locktable;
/* Try to autodetect */
if (!proto[0] || !table[0]) {
error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift, silent);
if (error)
return error;
if (!proto[0])
proto = sdp->sd_sb.sb_lockproto;
if (!table[0])
table = sdp->sd_sb.sb_locktable;
}
if (!table[0])
table = sdp->sd_vfs->s_id;
strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN);
strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN);
table = sdp->sd_table_name;
while ((table = strchr(table, '/')))
*table = '_';
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 122 | 68.54% | 2 | 33.33% |
david teigland | david teigland | 26 | 14.61% | 1 | 16.67% |
robert s. peterson | robert s. peterson | 17 | 9.55% | 1 | 16.67% |
cheng renquan | cheng renquan | 7 | 3.93% | 1 | 16.67% |
jean delvare | jean delvare | 6 | 3.37% | 1 | 16.67% |
| Total | 178 | 100.00% | 6 | 100.00% |
static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
int undo)
{
int error = 0;
if (undo)
goto fail_trans;
error = gfs2_glock_nq_num(sdp,
GFS2_MOUNT_LOCK, &gfs2_nondisk_glops,
LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE,
mount_gh);
if (error) {
fs_err(sdp, "can't acquire mount glock: %d\n", error);
goto fail;
}
error = gfs2_glock_nq_num(sdp,
GFS2_LIVE_LOCK, &gfs2_nondisk_glops,
LM_ST_SHARED,
LM_FLAG_NOEXP | GL_EXACT,
&sdp->sd_live_gh);
if (error) {
fs_err(sdp, "can't acquire live glock: %d\n", error);
goto fail_mount;
}
error = gfs2_glock_get(sdp, GFS2_RENAME_LOCK, &gfs2_nondisk_glops,
CREATE, &sdp->sd_rename_gl);
if (error) {
fs_err(sdp, "can't create rename glock: %d\n", error);
goto fail_live;
}
error = gfs2_glock_get(sdp, GFS2_FREEZE_LOCK, &gfs2_freeze_glops,
CREATE, &sdp->sd_freeze_gl);
if (error) {
fs_err(sdp, "can't create transaction glock: %d\n", error);
goto fail_rename;
}
return 0;
fail_trans:
gfs2_glock_put(sdp->sd_freeze_gl);
fail_rename:
gfs2_glock_put(sdp->sd_rename_gl);
fail_live:
gfs2_glock_dq_uninit(&sdp->sd_live_gh);
fail_mount:
gfs2_glock_dq_uninit(mount_gh);
fail:
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david teigland | david teigland | 223 | 98.24% | 1 | 50.00% |
benjamin marzinski | benjamin marzinski | 4 | 1.76% | 1 | 50.00% |
| Total | 227 | 100.00% | 2 | 100.00% |
static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr,
u64 no_addr, const char *name)
{
struct gfs2_sbd *sdp = sb->s_fs_info;
struct dentry *dentry;
struct inode *inode;
inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0,
GFS2_BLKST_FREE /* ignore */);
if (IS_ERR(inode)) {
fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode));
return PTR_ERR(inode);
}
dentry = d_make_root(inode);
if (!dentry) {
fs_err(sdp, "can't alloc %s dentry\n", name);
return -ENOMEM;
}
*dptr = dentry;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 119 | 95.97% | 5 | 62.50% |
andreas gruenbacher | andreas gruenbacher | 3 | 2.42% | 1 | 12.50% |
benjamin marzinski | benjamin marzinski | 1 | 0.81% | 1 | 12.50% |
al viro | al viro | 1 | 0.81% | 1 | 12.50% |
| Total | 124 | 100.00% | 8 | 100.00% |
static int init_sb(struct gfs2_sbd *sdp, int silent)
{
struct super_block *sb = sdp->sd_vfs;
struct gfs2_holder sb_gh;
u64 no_addr;
int ret;
ret = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,
LM_ST_SHARED, 0, &sb_gh);
if (ret) {
fs_err(sdp, "can't acquire superblock glock: %d\n", ret);
return ret;
}
ret = gfs2_read_sb(sdp, silent);
if (ret) {
fs_err(sdp, "can't read superblock: %d\n", ret);
goto out;
}
/* Set up the buffer cache and SB for real */
if (sdp->sd_sb.sb_bsize < bdev_logical_block_size(sb->s_bdev)) {
ret = -EINVAL;
fs_err(sdp, "FS block size (%u) is too small for device "
"block size (%u)\n",
sdp->sd_sb.sb_bsize, bdev_logical_block_size(sb->s_bdev));
goto out;
}
if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {
ret = -EINVAL;
fs_err(sdp, "FS block size (%u) is too big for machine "
"page size (%u)\n",
sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE);
goto out;
}
sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
/* Get the root inode */
no_addr = sdp->sd_sb.sb_root_dir.no_addr;
ret = gfs2_lookup_root(sb, &sdp->sd_root_dir, no_addr, "root");
if (ret)
goto out;
/* Get the master inode */
no_addr = sdp->sd_sb.sb_master_dir.no_addr;
ret = gfs2_lookup_root(sb, &sdp->sd_master_dir, no_addr, "master");
if (ret) {
dput(sdp->sd_root_dir);
goto out;
}
sb->s_root = dget(sdp->sd_args.ar_meta ? sdp->sd_master_dir : sdp->sd_root_dir);
out:
gfs2_glock_dq_uninit(&sb_gh);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david teigland | david teigland | 192 | 63.16% | 1 | 11.11% |
steven whitehouse | steven whitehouse | 107 | 35.20% | 6 | 66.67% |
robert s. peterson | robert s. peterson | 3 | 0.99% | 1 | 11.11% |
martin k. petersen | martin k. petersen | 2 | 0.66% | 1 | 11.11% |
| Total | 304 | 100.00% | 9 | 100.00% |
static void gfs2_others_may_mount(struct gfs2_sbd *sdp)
{
char *message = "FIRSTMOUNT=Done";
char *envp[] = { message, NULL };
fs_info(sdp, "first mount done, others may mount\n");
if (sdp->sd_lockstruct.ls_ops->lm_first_done)
sdp->sd_lockstruct.ls_ops->lm_first_done(sdp);
kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 45 | 66.18% | 2 | 66.67% |
david teigland | david teigland | 23 | 33.82% | 1 | 33.33% |
| Total | 68 | 100.00% | 3 | 100.00% |
/**
* gfs2_jindex_hold - Grab a lock on the jindex
* @sdp: The GFS2 superblock
* @ji_gh: the holder for the jindex glock
*
* Returns: errno
*/
static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
{
struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex);
struct qstr name;
char buf[20];
struct gfs2_jdesc *jd;
int error;
name.name = buf;
mutex_lock(&sdp->sd_jindex_mutex);
for (;;) {
error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, ji_gh);
if (error)
break;
name.len = sprintf(buf, "journal%u", sdp->sd_journals);
name.hash = gfs2_disk_hash(name.name, name.len);
error = gfs2_dir_check(sdp->sd_jindex, &name, NULL);
if (error == -ENOENT) {
error = 0;
break;
}
gfs2_glock_dq_uninit(ji_gh);
if (error)
break;
error = -ENOMEM;
jd = kzalloc(sizeof(struct gfs2_jdesc), GFP_KERNEL);
if (!jd)
break;
INIT_LIST_HEAD(&jd->extent_list);
INIT_LIST_HEAD(&jd->jd_revoke_list);
INIT_WORK(&jd->jd_work, gfs2_recover_func);
jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1);
if (!jd->jd_inode || IS_ERR(jd->jd_inode)) {
if (!jd->jd_inode)
error = -ENOENT;
else
error = PTR_ERR(jd->jd_inode);
kfree(jd);
break;
}
spin_lock(&sdp->sd_jindex_spin);
jd->jd_jid = sdp->sd_journals++;
list_add_tail(&jd->jd_list, &sdp->sd_jindex_list);
spin_unlock(&sdp->sd_jindex_spin);
}
mutex_unlock(&sdp->sd_jindex_mutex);
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
steven whitehouse | steven whitehouse | 304 | 96.82% | 2 | 50.00% |
robert s. peterson | robert s. peterson | 8 | 2.55% | 1 | 25.00% |
tejun heo | tejun heo | 2 | 0.64% | 1 | 25.00% |
| Total | 314 | 100.00% | 4 | 100.00% |
/**
* check_journal_clean - Make sure a journal is clean for a spectator mount
* @sdp: The GFS2 superblock
* @jd: The journal descriptor
*
* Returns: 0 if the journal is clean or locked, else an error
*/
static int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd)
{
int error;
struct gfs2_holder j_gh;
struct gfs2_log_header_host head;
struct gfs2_inode *ip;
ip = GFS2_I(jd->jd_inode);
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_NOEXP |
GL_EXACT | GL_NOCACHE, &j_gh);
if (error) {