diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h index 877448c..d3f7635 100644 --- a/gfs2/fsck/fsck.h +++ b/gfs2/fsck/fsck.h @@ -4,8 +4,6 @@ #include "libgfs2.h" #include "osi_tree.h" -#define FSCK_MAX_FORMAT (1801) - #define FSCK_HASH_SHIFT (13) #define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT) #define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1) diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c index d1c620a..ebe62b9 100644 --- a/gfs2/fsck/initialize.c +++ b/gfs2/fsck/initialize.c @@ -1334,12 +1334,12 @@ static int fill_super_block(struct gfs2_sbd *sdp) if (sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize){ log_crit( _("GFS superblock is larger than the blocksize!\n")); log_debug("sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize\n"); - return FSCK_ERROR; + return -1; } if (compute_constants(sdp)) { log_crit("%s\n", _("Failed to compute file system constants")); - return FSCK_ERROR; + exit(FSCK_ERROR); } ret = read_sb(sdp); if (ret < 0) { @@ -1348,15 +1348,10 @@ static int fill_super_block(struct gfs2_sbd *sdp) /* Now that we've tried to repair it, re-read it. */ ret = read_sb(sdp); if (ret < 0) - return FSCK_ERROR; + return -1; } if (sdp->gfs1) sbd1 = (struct gfs_sb *)&sdp->sd_sb; - else if (sdp->sd_sb.sb_fs_format > FSCK_MAX_FORMAT) { - log_crit(_("Unsupported gfs2 format found: %"PRIu32"\n"), sdp->sd_sb.sb_fs_format); - log_crit(_("A newer fsck.gfs2 is required to check this file system.\n")); - return FSCK_USAGE; - } return 0; } @@ -1561,7 +1556,6 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, int *all_clean) { int clean_journals = 0, open_flag; - int err; *all_clean = 0; @@ -1607,9 +1601,8 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, } /* read in sb from disk */ - err = fill_super_block(sdp); - if (err != FSCK_OK) - return err; + if (fill_super_block(sdp)) + return FSCK_ERROR; /* Change lock protocol to be fsck_* instead of lock_* */ if (!opts.no && preen_is_safe(sdp, preen, force_check)) { diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c index e0ea491..a828946 100644 --- a/gfs2/libgfs2/meta.c +++ b/gfs2/libgfs2/meta.c @@ -940,7 +940,6 @@ int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val) { char *fieldp = blk + field->offset; - uint64_t num = *(uint64_t *)val; if (field->flags & LGFS2_MFF_UUID) { memcpy(fieldp, val, 16); @@ -960,16 +959,16 @@ int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const voi switch(field->length) { case sizeof(uint8_t): - *fieldp = (uint8_t)num; + *fieldp = *(uint8_t *)val; return 0; case sizeof(uint16_t): - *(uint16_t *)fieldp = cpu_to_be16((uint16_t)num); + *(uint16_t *)fieldp = cpu_to_be16(*(uint16_t *)val); return 0; case sizeof(uint32_t): - *(uint32_t *)fieldp = cpu_to_be32((uint32_t)num); + *(uint32_t *)fieldp = cpu_to_be32(*(uint32_t *)val); return 0; case sizeof(uint64_t): - *(uint64_t *)fieldp = cpu_to_be64((uint64_t)num); + *(uint64_t *)fieldp = cpu_to_be64(*(uint64_t *)val); return 0; default: /* Will never happen */ diff --git a/gfs2/libgfs2/recovery.c b/gfs2/libgfs2/recovery.c index 06f8111..6b14bf9 100644 --- a/gfs2/libgfs2/recovery.c +++ b/gfs2/libgfs2/recovery.c @@ -241,7 +241,7 @@ int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head) lh->lh_sequence = cpu_to_be64(head->lh_sequence + 1); lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT); lh->lh_blkno = cpu_to_be32(lblock); - hash = lgfs2_log_header_hash(bh->b_data); + hash = gfs2_disk_hash((const char *)lh, sizeof(struct gfs2_log_header)); lh->lh_hash = cpu_to_be32(hash); bmodified(bh); brelse(bh); diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index ad044d0..190715e 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -332,7 +332,7 @@ static uint64_t align_block(const uint64_t base, const uint64_t align) */ uint64_t lgfs2_rgrp_align_addr(const lgfs2_rgrps_t rgs, uint64_t addr) { - return align_block(addr, rgs->align_off); + return align_block(addr, rgs->align); } /** diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c index 7592564..6e7d8c2 100644 --- a/gfs2/libgfs2/super.c +++ b/gfs2/libgfs2/super.c @@ -29,18 +29,11 @@ int check_sb(struct gfs2_sb *sb) errno = EIO; return -1; } - /* Check for gfs1 */ if (sb->sb_fs_format == GFS_FORMAT_FS && sb->sb_header.mh_format == GFS_FORMAT_SB && sb->sb_multihost_format == GFS_FORMAT_MULTI) { return 1; } - /* It's gfs2. Check format number is in a sensible range. */ - if (sb->sb_fs_format < GFS2_FORMAT_FS || - sb->sb_fs_format > 1899) { - errno = EINVAL; - return -1; - } return 2; } diff --git a/gfs2/man/fsck.gfs2.8 b/gfs2/man/fsck.gfs2.8 index 9e9f925..b2b326f 100644 --- a/gfs2/man/fsck.gfs2.8 +++ b/gfs2/man/fsck.gfs2.8 @@ -1,11 +1,11 @@ .TH fsck.gfs2 8 .SH NAME -fsck.gfs2 - offline GFS and GFS2 file system checker +fsck.gfs2 - Offline GFS and GFS2 file system checker .SH SYNOPSIS .B fsck.gfs2 -[\fIoptions\fR] \fIdevice\fR +[\fIOPTION\fR]... \fIDEVICE\fR .SH WARNING All computers \fImust\fP have the filesystem unmounted before running @@ -13,22 +13,30 @@ fsck.gfs2. Failure to unmount from all nodes in a cluster will likely result in filesystem corruption. .SH DESCRIPTION -fsck.gfs2 will check that the GFS or GFS2 file system on a device is -structurally valid. It should not be run on a mounted file system. If file -system corruption is detected, it will attempt to repair the file system. -There is a limit to what fsck.gfs2 can do. If important file system structures -are destroyed, such that the checker cannot determine what the repairs should -be, reparations could fail. +fsck.gfs2 will check that the GFS or GFS2 file system on a device is structurally valid. +It should not be run on a mounted file system. If file system corruption is +detected, it will attempt to repair the file system. There is a limit to what +fsck.gfs2 can do. If important file system structures are destroyed, such that +the checker cannot determine what the repairs should be, reparations could +fail. -Other file system checkers will not check the file system if it is "clean" -(i.e. unmounted since the last use). With gfs2, storage may be shared among -several nodes in a cluster, and therefore problems may have been introduced on -a different computer. Therefore, fsck.gfs2 will always check the file system -unless the -p (preen) option is used, in which case it follows special rules +GFS2 is a journaled file system, and as such should be able to repair damage to +the file system on its own. However, faulty hardware has the ability to write +incomplete blocks to a file system thereby causing corruption that GFS2 cannot +fix. The first step to ensuring a healthy file system is the selection of +reliable hardware (i.e. storage systems that will write complete blocks - even +in the event of power failure). + +Note: Most file system checkers will not check the file system if it is +"clean" (i.e. unmounted since the last use). The fsck.gfs program behaves +differently because the storage may be shared among several nodes in a +cluster, and therefore problems may have been introduced on a different +computer. Therefore, fsck.gfs2 will always check the file system unless +the -p (preen) option is used, in which case it follows special rules (see below). -fsck.gfs2 will log a message to the system log on start and exit to aid -debugging and administration. +fsck.gfs2 will log to the system log on start and exit to aid debugging and +administration. .SH OPTIONS .TP \fB-a\fP @@ -78,8 +86,3 @@ Yes to all questions. By specifying this option, fsck.gfs2 will not prompt befor changes. This option may not be used with the \fB-n\fP or \fB-p\fP/\fB-a\fP options. - -.SH SEE ALSO -.BR gfs2 (5), -.BR gfs2_jadd (8), -.BR gfs2_grow (8) diff --git a/gfs2/man/gfs2.5 b/gfs2/man/gfs2.5 index 8f67ce2..56d1a00 100644 --- a/gfs2/man/gfs2.5 +++ b/gfs2/man/gfs2.5 @@ -21,20 +21,6 @@ mounts which are equivalent to mounting a read-only block device and as such can neither recover a journal or write to the filesystem, so do not require a journal assigned to them. -The GFS2 documentation has been split into a number of sections: - -\fBmkfs.gfs2\fP(8) Create a GFS2 filesystem -.br -\fBfsck.gfs2\fP(8) The GFS2 filesystem checker -.br -\fBgfs2_grow\fP(8) Growing a GFS2 filesystem -.br -\fBgfs2_jadd\fP(8) Adding a journal to a GFS2 filesystem -.br -\fBtunegfs2\fP(8) Tool to manipulate GFS2 superblocks -.br -\fBgfs2_edit\fP(8) A GFS2 debug tool (use with caution) - .SH MOUNT OPTIONS .TP @@ -48,7 +34,7 @@ currently these are \fIlock_nolock\fR and \fIlock_dlm\fR. The default lock protocol name is written to disk initially when creating the filesystem with \fBmkfs.gfs2\fP(8), -p option. It can be changed on-disk by -using the \fBtunegfs2\fP(8) command. +using the \fBgfs2_tool\fP(8) utility's \fBsb proto\fP command. The \fBlockproto\fP mount option should be used only under special circumstances in which you want to temporarily use a different lock protocol @@ -70,7 +56,7 @@ The format of \fILockTableName\fR is lock-module-specific. For The default cluster/filesystem name is written to disk initially when creating the filesystem with \fBmkfs.gfs2\fP(8), -t option. It can be changed on-disk -by using the \fBtunegfs2\fP(8) command. +by using the \fBgfs2_tool\fP(8) utility's \fBsb table\fP command. The \fBlocktable\fP mount option should be used only under special circumstances in which you want to mount the filesystem in a different cluster, @@ -214,55 +200,220 @@ versa. Finally, when first enabling this option on a filesystem that had been previously mounted without it, you must make sure that there are no outstanding cookies being cached by other software, such as NFS. +.SH BUGS + +GFS2 doesn't support \fBerrors=\fP\fIremount-ro\fR or \fBdata=\fP\fIjournal\fR. +It is not possible to switch support for user and group quotas on and +off independently of each other. Some of the error messages are rather +cryptic, if you encounter one of these messages check firstly that gfs_controld +is running and secondly that you have enough journals on the filesystem +for the number of nodes in use. + +.SH SEE ALSO + +\fBmount\fP(8) for general mount options, +\fBchmod\fP(1) and \fBchmod\fP(2) for access permission flags, +\fBacl\fP(5) for access control lists, +\fBlvm\fP(8) for volume management, +\fBccs\fP(7) for cluster management, +\fBumount\fP(8), +\fBinitrd\fP(4). + +The GFS2 documentation has been split into a number of sections: + +\fBgfs2_edit\fP(8) A GFS2 debug tool (use with caution) +\fBfsck.gfs2\fP(8) The GFS2 file system checker +\fBgfs2_grow\fP(8) Growing a GFS2 file system +\fBgfs2_jadd\fP(8) Adding a journal to a GFS2 file system +\fBmkfs.gfs2\fP(8) Make a GFS2 file system +\fBgfs2_quota\fP(8) Manipulate GFS2 disk quotas +\fBgfs2_tool\fP(8) Tool to manipulate a GFS2 file system (obsolete) +\fBtunegfs2\fP(8) Tool to manipulate GFS2 superblocks + .SH SETUP -GFS2 clustering is driven by the dlm, which depends on dlm_controld to provide -clustering from userspace. dlm_controld clustering is built on corosync -cluster/group membership and messaging. GFS2 also requires clustered lvm which -is provided by lvmlockd or, previously, clvmd. Refer to the documentation for -each of these components and ensure that they are configured before setting up -a GFS2 filesystem. Also refer to your distribution's documentation for any -specific support requirements. +GFS2 clustering is driven by the dlm, which depends on dlm_controld to +provide clustering from userspace. dlm_controld clustering is built on +corosync cluster/group membership and messaging. + +Follow these steps to manually configure and run gfs2/dlm/corosync. + +.B 1. create /etc/corosync/corosync.conf and copy to all nodes + +In this sample, replace cluster_name and IP addresses, and add nodes as +needed. If using only two nodes, uncomment the two_node line. +See corosync.conf(5) for more information. + +.nf +totem { + version: 2 + secauth: off + cluster_name: abc +} + +nodelist { + node { + ring0_addr: 10.10.10.1 + nodeid: 1 + } + node { + ring0_addr: 10.10.10.2 + nodeid: 2 + } + node { + ring0_addr: 10.10.10.3 + nodeid: 3 + } +} + +quorum { + provider: corosync_votequorum +# two_node: 1 +} + +logging { + to_syslog: yes +} +.fi + +.PP + +.B 2. start corosync on all nodes + +.nf +systemctl start corosync +.fi + +Run corosync-quorumtool to verify that all nodes are listed. + +.PP + +.B 3. create /etc/dlm/dlm.conf and copy to all nodes + +.B * +To use no fencing, use this line: -Ensure that gfs2-utils is installed on all nodes which mount the filesystem as -it provides scripts required for correct withdraw event response. +.nf +enable_fencing=0 +.fi -.B 1. Create the gfs2 filesystem +.B * +To use no fencing, but exercise fencing functions, use this line: + +.nf +fence_all /bin/true +.fi + +The "true" binary will be executed for all nodes and will succeed (exit 0) +immediately. + +.B * +To use manual fencing, use this line: + +.nf +fence_all /bin/false +.fi + +The "false" binary will be executed for all nodes and will fail (exit 1) +immediately. + +When a node fails, manually run: dlm_tool fence_ack + +.B * +To use stonith/pacemaker for fencing, use this line: + +.nf +fence_all /usr/sbin/dlm_stonith +.fi + +The "dlm_stonith" binary will be executed for all nodes. If +stonith/pacemaker systems are not available, dlm_stonith will fail and +this config becomes the equivalent of the previous /bin/false config. + +.B * +To use an APC power switch, use these lines: + +.nf +device apc /usr/sbin/fence_apc ipaddr=1.1.1.1 login=admin password=pw +connect apc node=1 port=1 +connect apc node=2 port=2 +connect apc node=3 port=3 +.fi + +Other network switch based agents are configured similarly. + +.B * +To use sanlock/watchdog fencing, use these lines: + +.nf +device wd /usr/sbin/fence_sanlock path=/dev/fence/leases +connect wd node=1 host_id=1 +connect wd node=2 host_id=2 +unfence wd +.fi + +See fence_sanlock(8) for more information. + +.B * +For other fencing configurations see dlm.conf(5) man page. + +.PP + +.B 4. start dlm_controld on all nodes + +.nf +systemctl start dlm +.fi + +Run "dlm_tool status" to verify that all nodes are listed. + +.PP + +.B 5. if using clvm, start clvmd on all nodes + +systemctl clvmd start + +.PP + +.B 6. make new gfs2 file systems mkfs.gfs2 -p lock_dlm -t cluster_name:fs_name -j num /path/to/storage -The cluster_name must match the name configured in corosync (and thus dlm). -The fs_name must be a unique name for the filesystem in the cluster. -The -j option is the number of journals to create; there must -be one for each node that will mount the filesystem. +The cluster_name must match the name used in step 1 above. +The fs_name must be a unique name in the cluster. +The -j option is the number of journals to create, there must +be one for each node that will mount the fs. .PP -.B 2. Mount the gfs2 filesystem -If you are using a clustered resource manager, see its documentation for -enabling a gfs2 filesystem resource. Otherwise, run: +.B 7. mount gfs2 file systems mount /path/to/storage /mountpoint Run "dlm_tool ls" to verify the nodes that have each fs mounted. .PP -.B 3. Shut down -If you are using a clustered resource manager, see its documentation for -disabling a gfs2 filesystem resource. Otherwise, run: +.B 8. shut down +.nf umount -a -t gfs2 +systemctl clvmd stop +systemctl dlm stop +systemctl corosync stop +.fi .PP -.SH SEE ALSO -\fBmount\fP(8) and \fBumount\fP(8) for general mount information, -\fBchmod\fP(1) and \fBchmod\fP(2) for access permission flags, -\fBacl\fP(5) for access control lists, -\fBlvm\fP(8) for volume management, -\fBdlm_controld\fP(8), -\fBdlm_tool\fP(8), -\fBdlm.conf\fP(5), -\fBcorosync\fP(8), -\fBcorosync.conf\fP(5), +.B More setup information: +.br +.BR dlm_controld (8), +.br +.BR dlm_tool (8), +.br +.BR dlm.conf (5), +.br +.BR corosync (8), +.br +.BR corosync.conf (5) +.br diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c index ea89c96..efe91e3 100644 --- a/gfs2/mkfs/main_jadd.c +++ b/gfs2/mkfs/main_jadd.c @@ -42,13 +42,15 @@ struct jadd_opts { #define JA_FL_SET 0 #define JA_FL_CLEAR 1 -static int set_flags(int fd, int op, uint32_t flags) +static void set_flags(int fd, int op, uint32_t flags) { + int err; uint32_t val; - if (ioctl(fd, FS_IOC_GETFLAGS, &val)) { + err = ioctl(fd, FS_IOC_GETFLAGS, &val); + if (err) { perror("GETFLAGS"); - return -1; + exit(EXIT_FAILURE); } if (op == JA_FL_SET) @@ -56,11 +58,11 @@ static int set_flags(int fd, int op, uint32_t flags) else if (op == JA_FL_CLEAR) val &= ~flags; - if (ioctl(fd, FS_IOC_SETFLAGS, &val)) { + err = ioctl(fd, FS_IOC_SETFLAGS, &val); + if (err) { perror("SETFLAGS"); - return -1; + exit(EXIT_FAILURE); } - return 0; } static int rename2system(struct jadd_opts *opts, const char *new_dir, const char *new_name) @@ -241,214 +243,186 @@ static void print_results(struct jadd_opts *opts) static int create_new_inode(struct jadd_opts *opts, uint64_t *addr) { char *name = opts->new_inode; - int fd, error = 0; + int fd; + int error; for (;;) { fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600); if (fd >= 0) break; if (errno == EEXIST) { - if (unlink(name)) { + error = unlink(name); + if (error){ perror("unlink"); - return -1; + exit(EXIT_FAILURE); } - continue; + } else{ + perror("create"); + exit(EXIT_FAILURE); } - perror("create"); - return -1; } - if (addr != NULL) { struct stat st; - if ((error = fstat(fd, &st))) { - perror("fstat"); - return close(fd); - } + fstat(fd, &st); *addr = st.st_ino; } return fd; } -static int add_ir(struct jadd_opts *opts) +static void add_ir(struct jadd_opts *opts) { - int fd, error = 0; + int fd; char new_name[256]; - struct gfs2_inum_range ir; - - if ((fd = create_new_inode(opts, NULL)) < 0) - return fd; + int error; - if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL))) - goto close_fd; + fd = create_new_inode(opts, NULL); - memset(&ir, 0, sizeof(struct gfs2_inum_range)); - if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != - sizeof(struct gfs2_inum_range)) { - perror("add_ir write"); - error = -1; - goto close_fd; - } + { + struct gfs2_inum_range ir; - if ((error = fsync(fd))) { - perror("add_ir fsync"); - goto close_fd; + set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); + memset(&ir, 0, sizeof(struct gfs2_inum_range)); + if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != + sizeof(struct gfs2_inum_range)) { + perror("add_ir"); + exit(EXIT_FAILURE); + } } + close(fd); sprintf(new_name, "inum_range%u", opts->journals); error = rename2system(opts, opts->per_node, new_name); - if (error < 0 && errno != EEXIST) { + if (error < 0 && errno != EEXIST){ perror("add_ir rename2system"); - goto close_fd; + exit(EXIT_FAILURE); } -close_fd: - return close(fd) || error; } -static int add_sc(struct jadd_opts *opts) +static void add_sc(struct jadd_opts *opts) { - int fd, error = 0; + int fd; char new_name[256]; - struct gfs2_statfs_change sc; + int error; - if ((fd = create_new_inode(opts, NULL)) < 0) - return fd; + fd = create_new_inode(opts, NULL); - if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL))) - goto close_fd; + { + struct gfs2_statfs_change sc; + set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); - memset(&sc, 0, sizeof(struct gfs2_statfs_change)); - if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != - sizeof(struct gfs2_statfs_change)) { - perror("add_sc write"); - error = -1; - goto close_fd; + memset(&sc, 0, sizeof(struct gfs2_statfs_change)); + if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != + sizeof(struct gfs2_statfs_change)) { + perror("add_sc"); + exit(EXIT_FAILURE); + } } - if ((error = fsync(fd))) { - perror("add_sc fsync"); - goto close_fd; - } + close(fd); sprintf(new_name, "statfs_change%u", opts->journals); error = rename2system(opts, opts->per_node, new_name); if (error < 0 && errno != EEXIST){ perror("add_sc rename2system"); - goto close_fd; + exit(EXIT_FAILURE); } -close_fd: - return close(fd) || error; } -static int add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) +static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) { - int fd, error = 0; - char new_name[256], buf[sdp->bsize]; - unsigned int blocks = - sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); - unsigned int x; - struct gfs2_meta_header mh; - - if ((fd = create_new_inode(opts, NULL)) < 0) - return fd; - - if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL))) - goto close_fd; - - memset(buf, 0, sdp->bsize); - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc write"); - error = -1; - goto close_fd; + int fd; + char new_name[256]; + int error; + + fd = create_new_inode(opts, NULL); + + { + char buf[sdp->bsize]; + unsigned int blocks = + sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); + unsigned int x; + struct gfs2_meta_header mh; + + set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); + memset(buf, 0, sdp->bsize); + + for (x=0; xbsize) != sdp->bsize) { + perror("add_qc"); + exit(EXIT_FAILURE); + } } - } - if ((error = lseek(fd, 0, SEEK_SET)) < 0) { - perror("add_qc lseek"); - goto close_fd; - } + lseek(fd, 0, SEEK_SET); + + memset(&mh, 0, sizeof(struct gfs2_meta_header)); + mh.mh_magic = GFS2_MAGIC; + mh.mh_type = GFS2_METATYPE_QC; + mh.mh_format = GFS2_FORMAT_QC; + gfs2_meta_header_out(&mh, buf); - memset(&mh, 0, sizeof(struct gfs2_meta_header)); - mh.mh_magic = GFS2_MAGIC; - mh.mh_type = GFS2_METATYPE_QC; - mh.mh_format = GFS2_FORMAT_QC; - gfs2_meta_header_out(&mh, buf); - - for (x=0; xbsize) != sdp->bsize) { - perror("add_qc write"); - error = 1; - goto close_fd; + for (x=0; xbsize) != sdp->bsize) { + perror("add_qc"); + exit(EXIT_FAILURE); + } } - if ((error = fsync(fd))) { + + error = fsync(fd); + if (error){ perror("add_qc fsync"); - goto close_fd; + exit(EXIT_FAILURE); } } + close(fd); + sprintf(new_name, "quota_change%u", opts->journals); error = rename2system(opts, opts->per_node, new_name); if (error < 0 && errno != EEXIST){ perror("add_qc rename2system"); - goto close_fd; + exit(EXIT_FAILURE); } -close_fd: - return close(fd) || error; } -static int gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) +static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) { struct statfs statbuf; - if (statfs(opts->path, &statbuf) < 0) { perror(opts->path); - return -1; + exit(EXIT_FAILURE); } - sdp->bsize = statbuf.f_bsize; - sdp->blks_total = statbuf.f_blocks; - sdp->blks_alloced = sdp->blks_total - statbuf.f_bfree; - - return 0; } -static int find_current_journals(struct jadd_opts *opts) +static void find_current_journals(struct jadd_opts *opts) { struct dirent *dp; DIR *dirp; unsigned existing_journals = 0; - int ret = 0; dirp = opendir(opts->jindex); if (!dirp) { perror("jindex"); - ret = -1; - goto out; + exit(EXIT_FAILURE); } while (dirp) { if ((dp = readdir(dirp)) != NULL) { if (strncmp(dp->d_name, "journal", 7) == 0) existing_journals++; } else - goto close_fd; + goto close; } -close_fd: - if ((ret = closedir(dirp))) - goto out; - +close: + closedir(dirp); if (existing_journals == 0) { - errno = EINVAL; - perror("No journals found. Did you run mkfs.gfs2 correctly?\n"); - ret = -1; - goto out; + die( _("No journals found. Did you run mkfs.gfs2 correctly?\n")); } opts->orig_journals = existing_journals; -out: - return ret; } #ifdef GFS2_HAS_LH_V2 @@ -474,118 +448,83 @@ static uint64_t find_block_address(int fd, off_t offset, unsigned bsize) } #endif -static int add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) +static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) { - int fd, error = 0; - char new_name[256], buf[sdp->bsize]; - unsigned int x, blocks = - sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); - struct gfs2_log_header lh; - uint64_t seq = RANDOM(blocks), addr; - off_t off = 0; - - if ((fd = create_new_inode(opts, &addr)) < 0) - return fd; - - if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL))) - goto close_fd; - - memset(buf, 0, sdp->bsize); - for (x=0; xbsize) != sdp->bsize) { - perror("add_j write"); - error = -1; - goto close_fd; + int fd; + char new_name[256]; + int error; + uint64_t addr; + + fd = create_new_inode(opts, &addr); + + { + char buf[sdp->bsize]; + unsigned int blocks = + sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); + unsigned int x; + struct gfs2_log_header lh; + uint64_t seq = RANDOM(blocks); + off_t off = 0; + + set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); + memset(buf, 0, sdp->bsize); + for (x=0; xbsize) != sdp->bsize) { + perror("add_j"); + exit(EXIT_FAILURE); + } } - } - if ((error = lseek(fd, 0, SEEK_SET)) < 0) { - perror("add_j lseek"); - goto close_fd; - } + lseek(fd, 0, SEEK_SET); - memset(&lh, 0, sizeof(struct gfs2_log_header)); - lh.lh_header.mh_magic = GFS2_MAGIC; - lh.lh_header.mh_type = GFS2_METATYPE_LH; - lh.lh_header.mh_format = GFS2_FORMAT_LH; - lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT; -#ifdef GFS2_HAS_LH_V2 - lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE; - lh.lh_jinode = addr; -#endif - for (x=0; xlh_hash = cpu_to_be32(hash); + for (x=0; xlh_hash = cpu_to_be32(hash); #ifdef GFS2_HAS_LH_V2 - if (!(blk_addr = find_block_address(fd, off, sdp->bsize))) { - error = -1; - goto close_fd; - } - ((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64(blk_addr); - hash = lgfs2_log_header_crc(buf, sdp->bsize); - ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); + ((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64( + find_block_address(fd, off, sdp->bsize)); + hash = lgfs2_log_header_crc(buf, sdp->bsize); + ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); #endif - if (write(fd, buf, sdp->bsize) != sdp->bsize) { - perror("add_j write"); - error = -1; - goto close_fd; - } + if (write(fd, buf, sdp->bsize) != sdp->bsize) { + perror("add_j"); + exit(EXIT_FAILURE); + } - if (++seq == blocks) - seq = 0; - off += sdp->bsize; + if (++seq == blocks) + seq = 0; + off += sdp->bsize; + } - if ((error = fsync(fd))) { + error = fsync(fd); + if (error){ perror("add_j fsync"); - goto close_fd; + exit(EXIT_FAILURE); } } + close(fd); + sprintf(new_name, "journal%u", opts->journals); error = rename2system(opts, opts->jindex, new_name); if (error < 0 && errno != EEXIST){ perror("add_j rename2system"); - goto close_fd; - } -close_fd: - return close(fd) || error; -} - -static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts) -{ - /* Compute how much space we'll need for the new journals - * Number of blocks needed per added journal: - * 1 block for the ir inode - * 1 block for the sc inode - * for sizes of the qc and journal inodes, use lgfs2_space_for_data() - * to calculate. - */ - uint64_t blks_per_j, total_blks; - - blks_per_j = 1 + 1 + - lgfs2_space_for_data(sdp, sdp->bsize, sdp->qcsize << 20) + - lgfs2_space_for_data(sdp, sdp->bsize, sdp->jsize << 20); - total_blks = opts->journals * blks_per_j; - - if (total_blks > (sdp->blks_total - sdp->blks_alloced)) { - printf( _("\nInsufficient space on the device to add %u %uMB " - "journals (%uMB QC size)\n\n"), - opts->journals, sdp->jsize, sdp->qcsize); - printf( _("Required space : %*lu blks (%lu blks per " - "journal)\n"), 10, total_blks, blks_per_j); - printf( _("Available space : %*lu blks\n\n"), 10, - sdp->blks_total - sdp->blks_alloced); - errno = ENOSPC; - return -1; + exit(EXIT_FAILURE); } - return 0; } int main(int argc, char *argv[]) @@ -594,7 +533,7 @@ int main(int argc, char *argv[]) struct gfs2_sbd sbd, *sdp = &sbd; struct metafs mfs = {0}; struct mntent *mnt; - unsigned int total, ret = 0; + unsigned int total; setlocale(LC_ALL, ""); textdomain("gfs2-utils"); @@ -610,74 +549,52 @@ int main(int argc, char *argv[]) sbd.path_fd = lgfs2_open_mnt_dir(opts.path, O_RDONLY|O_CLOEXEC, &mnt); if (sbd.path_fd < 0) { - fprintf(stderr, "Error looking up mount '%s': %s\n", - opts.path, strerror(errno)); - ret = -1; - goto out; + fprintf(stderr, _("Error looking up mount '%s': %s\n"), opts.path, strerror(errno)); + exit(EXIT_FAILURE); } if (mnt == NULL) { - fprintf(stderr, "%s: not a mounted gfs2 file system\n", opts.path); - ret = -1; - goto close_sb; + fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), opts.path); + exit(EXIT_FAILURE); } - - if ((ret = gather_info(sdp, &opts))) - goto close_sb; - + gather_info(sdp, &opts); mfs.context = copy_context_opt(mnt); - if ((ret = mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug))) { + if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) { perror("GFS2 metafs"); - goto close_sb; + exit(EXIT_FAILURE); } - if ((ret = build_paths(mfs.path, &opts))) { + if (build_paths(mfs.path, &opts)) { perror(_("Failed to build paths")); - goto umount_meta; + exit(EXIT_FAILURE); } - if ((ret = compute_constants(sdp))) { + if (compute_constants(sdp)) { perror(_("Failed to compute file system constants")); - goto free_paths; - } - - if ((ret = find_current_journals(&opts))) - goto free_paths; - - if ((ret = check_fit(sdp, &opts))) { - perror(_("Failed to add journals")); - goto free_paths; + exit(EXIT_FAILURE); } + find_current_journals(&opts); total = opts.orig_journals + opts.journals; for (opts.journals = opts.orig_journals; opts.journals < total; opts.journals++) { if (metafs_interrupted) { - errno = 130; - goto free_paths; + cleanup_metafs(&mfs); + exit(130); } - if ((ret = add_ir(&opts))) - goto free_paths; - if ((ret = add_sc(&opts))) - goto free_paths; - if ((ret = add_qc(sdp, &opts))) - goto free_paths; - if ((ret = add_j(sdp, &opts))) - goto free_paths; + add_ir(&opts); + add_sc(&opts); + add_qc(sdp, &opts); + add_j(sdp, &opts); } -free_paths: free(opts.new_inode); free(opts.per_node); free(opts.jindex); -umount_meta: - sync(); - cleanup_metafs(&mfs); -close_sb: close(sdp->path_fd); -out: - if (!ret) - print_results(&opts); + cleanup_metafs(&mfs); + sync(); + print_results(&opts); - return ret; + return 0; } diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 09e756f..846b341 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -505,7 +505,7 @@ static unsigned choose_blocksize(struct mkfs_opts *opts) } if (!opts->got_bsize && got_topol) { if (dev->optimal_io_size <= getpagesize() && - dev->optimal_io_size >= GFS2_DEFAULT_BSIZE) + dev->optimal_io_size >= dev->minimum_io_size) bsize = dev->optimal_io_size; else if (dev->physical_sector_size <= getpagesize() && dev->physical_sector_size >= GFS2_DEFAULT_BSIZE) @@ -921,17 +921,11 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsiz will fit. For user-provided journal sizes, limit it to half of the fs. */ if (!opts->got_jsize) { int default_jsize = default_journal_size(sdp->bsize, sdp->device.length / opts->journals); - unsigned jsize_mb; - if (default_jsize < 0) { fprintf(stderr, _("gfs2 will not fit on this device.\n")); exit(1); } - jsize_mb = (default_jsize * sdp->bsize) >> 20; - if (jsize_mb < GFS2_MIN_JSIZE) - opts->jsize = GFS2_MIN_JSIZE; - else - opts->jsize = jsize_mb; + opts->jsize = (default_jsize * sdp->bsize) >> 20; } else if ((((opts->jsize * opts->journals) << 20) / sdp->bsize) > (sdp->device.length / 2)) { unsigned max_jsize = (sdp->device.length / 2 * sdp->bsize / opts->journals) >> 20; diff --git a/tests/fsck.at b/tests/fsck.at index 97a00a9..39a04d0 100644 --- a/tests/fsck.at +++ b/tests/fsck.at @@ -54,16 +54,3 @@ AT_CHECK([gfs2_edit -p journal0 field di_header.mh_magic 0 $GFS_TGT], 0, [ignore AT_CHECK([fsck.gfs2 -y $GFS_TGT], 1, [ignore], [ignore]) AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) AT_CLEANUP - -AT_SETUP([gfs2 format versions]) -AT_KEYWORDS(fsck.gfs2 fsck) -GFS_TGT_REGEN -AT_CHECK([mkfs.gfs2 -O -p lock_nolock ${GFS_TGT}], 0, [ignore], [ignore]) -AT_CHECK([echo "set sb { sb_fs_format: 1802 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore]) -# Unsupported format, FSCK_USAGE == 16 -AT_CHECK([fsck.gfs2 -y $GFS_TGT], 16, [ignore], [ignore]) -# Format out of range -AT_CHECK([echo "set sb { sb_fs_format: 4242 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -y $GFS_TGT], 1, [ignore], [ignore]) -AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) -AT_CLEANUP diff --git a/tests/mkfs.at b/tests/mkfs.at index e7ce8e8..ee444f5 100644 --- a/tests/mkfs.at +++ b/tests/mkfs.at @@ -78,8 +78,6 @@ AT_CLEANUP AT_SETUP([Min. journal size]) AT_KEYWORDS(mkfs.gfs2 mkfs) GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 8 $GFS_TGT]) -GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 1024 $GFS_TGT 511996]) -AT_CHECK([gfs2_edit -p journal0 field di_size $GFS_TGT | tr -d '\n'], 0, [8388608], [ignore]) AT_CLEANUP AT_SETUP([Max. quota change file size]) @@ -114,8 +112,6 @@ AT_CLEANUP AT_SETUP([Device i/o limits handling]) AT_KEYWORDS(mkfs.gfs2 mkfs) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:0:0:0:0 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:512:512:512 $GFS_TGT], 0, [ignore], [ignore]) -AT_CHECK([gfs2_edit -p sb field sb_bsize $GFS_TGT | tr -d '\n' ], 0, [4096], [ignore]) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:0:33553920:512 $GFS_TGT], 0, [ignore], [ignore]) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:8192:33553920:512 $GFS_TGT], 0, [ignore], [Warning: device is not properly aligned. This may harm performance. ]) @@ -126,8 +122,6 @@ AT_KEYWORDS(mkfs.gfs2 mkfs) AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_TGT], 0, [ignore], [ignore]) # Check rgrp alignment to minimum_io_size: 65536 / 4096 == 16 AT_CHECK([gfs2_edit -p rindex $GFS_TGT | grep ri_addr | awk '{print $2, $2 % 16; if ($2 % 16 != 0) { exit 1 }}'], 0, [ignore], [ignore]) -# rhbz#1698858 -AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:131072:6291456:512 $GFS_TGT], 0, [ignore], [ignore]) AT_CLEANUP AT_SETUP([Values of rg_skip])