diff options
Diffstat (limited to 'mount')
-rw-r--r-- | mount/Makefile.am | 8 | ||||
-rw-r--r-- | mount/fstab.c | 1 | ||||
-rw-r--r-- | mount/lomount.c | 84 | ||||
-rw-r--r-- | mount/loop.h | 2 | ||||
-rw-r--r-- | mount/losetup.8 | 15 | ||||
-rw-r--r-- | mount/mount.8 | 142 | ||||
-rw-r--r-- | mount/mount.c | 10 | ||||
-rw-r--r-- | mount/umount.c | 56 |
8 files changed, 247 insertions, 71 deletions
diff --git a/mount/Makefile.am b/mount/Makefile.am index 91860d23..5628cc0e 100644 --- a/mount/Makefile.am +++ b/mount/Makefile.am @@ -71,7 +71,6 @@ losetup_static_LDFLAGS = $(ldflags_static) losetup_static_CPPFLAGS = -DMAIN $(AM_CPPFLAGS) endif -if HAVE_BLKID if BUILD_LIBBLKID ldadd_common += $(ul_libblkid_la) ldadd_static += $(ul_libblkid_la) @@ -81,13 +80,6 @@ ldadd_common += $(BLKID_LIBS) ldadd_static += $(BLKID_LIBS_STATIC) cflags_common += $(BLKID_CFLAGS) endif -endif - -if HAVE_VOLUME_ID -ldadd_common += $(VOLUME_ID_LIBS) -ldadd_static += $(VOLUME_ID_LIBS_STATIC) -cflags_common += $(VOLUME_ID_CFLAGS) -endif if HAVE_SELINUX mount_LDADD += $(SELINUX_LIBS) diff --git a/mount/fstab.c b/mount/fstab.c index 13dda871..82e90f3a 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -404,6 +404,7 @@ getfs_by_spec (const char *spec) { mc = getfs_by_uuid (value); free(name); + free(value); return mc; } diff --git a/mount/lomount.c b/mount/lomount.c index 2768ea37..fd12ce29 100644 --- a/mount/lomount.c +++ b/mount/lomount.c @@ -65,8 +65,6 @@ loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info) return 0; } -#define DEV_LOOP_PATH "/dev/loop" -#define DEV_PATH "/dev" #define LOOPMAJOR 7 #define NLOOPS_DEFAULT 8 /* /dev/loop[0-7] */ @@ -148,10 +146,10 @@ looplist_open(struct looplist *ll, int flag) ll->flag = flag; ll->ncur = -1; - if (stat(DEV_PATH, &st) == -1 || (!S_ISDIR(st.st_mode))) + if (stat(_PATH_DEV, &st) == -1 || (!S_ISDIR(st.st_mode))) return -1; /* /dev doesn't exist */ - if (stat(DEV_LOOP_PATH, &st) == 0 && S_ISDIR(st.st_mode)) + if (stat(_PATH_DEV_LOOP, &st) == 0 && S_ISDIR(st.st_mode)) ll->flag |= LLFLG_SUBDIR; /* /dev/loop/ exists */ if ((ll->flag & LLFLG_USEDONLY) && @@ -184,8 +182,8 @@ looplist_open_dev(struct looplist *ll, int lnum) /* create a full device path */ snprintf(ll->name, sizeof(ll->name), ll->flag & LLFLG_SUBDIR ? - DEV_LOOP_PATH "/%d" : - DEV_PATH "/loop%d", + _PATH_DEV_LOOP "/%d" : + _PATH_DEV "loop%d", lnum); fd = open(ll->name, O_RDONLY); @@ -336,8 +334,8 @@ looplist_next(struct looplist *ll) */ if (!ll->minors) { ll->nminors = (ll->flag & LLFLG_SUBDIR) ? - loop_scandir(DEV_LOOP_PATH, &ll->minors, 0) : - loop_scandir(DEV_PATH, &ll->minors, 1); + loop_scandir(_PATH_DEV_LOOP, &ll->minors, 0) : + loop_scandir(_PATH_DEV, &ll->minors, 1); ll->ncur = -1; } for (++ll->ncur; ll->ncur < ll->nminors; ll->ncur++) { @@ -354,6 +352,28 @@ done: #ifdef MAIN static int +set_capacity(const char *device) +{ + int errsv; + int fd = open(device, O_RDONLY); + + if (fd == -1) + goto err; + + if (ioctl(fd, LOOP_SET_CAPACITY) != 0) + goto err; + + return 0; +err: + errsv = errno; + fprintf(stderr, _("loop: can't set capacity on device %s: %s\n"), + device, strerror (errsv)); + if (fd != -1) + close(fd); + return 2; +} + +static int show_loop_fd(int fd, char *device) { struct loop_info loopinfo; struct loop_info64 loopinfo64; @@ -483,8 +503,7 @@ show_associated_loop_devices(char *filename, unsigned long long offset, int isof /* check if the loopfile is already associated with the same given * parameters. * - * returns: -1 error - * 0 unused + * returns: 0 unused / error * 1 loop device already used */ static int @@ -499,17 +518,15 @@ is_associated(int dev, struct stat *file, unsigned long long offset, int isoff) file->st_ino == linfo64.lo_inode && (isoff == 0 || offset == linfo64.lo_offset)) ret = 1; - return ret; - } - if (ioctl(dev, LOOP_GET_STATUS, &linfo) == 0) { + + } else if (ioctl(dev, LOOP_GET_STATUS, &linfo) == 0) { if (file->st_dev == linfo.lo_device && file->st_ino == linfo.lo_inode && (isoff == 0 || offset == linfo.lo_offset)) ret = 1; - return ret; } - return errno == ENXIO ? 0 : -1; + return ret; } /* check if the loop file is already used with the same given @@ -555,18 +572,14 @@ loopfile_used_with(char *devname, const char *filename, unsigned long long offse if (!is_loop_device(devname)) return 0; - if (stat(filename, &statbuf) == -1) { - perror(filename); - return -1; - } + if (stat(filename, &statbuf) == -1) + return 0; fd = open(devname, O_RDONLY); - if (fd == -1) { - perror(devname); - return -1; - } - ret = is_associated(fd, &statbuf, offset, 1); + if (fd == -1) + return 0; + ret = is_associated(fd, &statbuf, offset, 1); close(fd); return ret; } @@ -950,6 +963,7 @@ usage(void) { " %1$s -a | --all list all used\n" " %1$s -d | --detach <loopdev> [<loopdev> ...] delete\n" " %1$s -f | --find find unused\n" + " %1$s -c | --set-capacity <loopdev> resize\n" " %1$s -j | --associated <file> [-o <num>] list all associated with <file>\n" " %1$s [ options ] {-f|--find|loopdev} <file> setup\n"), progname); @@ -976,7 +990,7 @@ int main(int argc, char **argv) { char *p, *offset, *sizelimit, *encryption, *passfd, *device, *file, *assoc; char *keysize; - int delete, find, c, all; + int delete, find, c, all, capacity; int res = 0; int showdev = 0; int ro = 0; @@ -986,6 +1000,7 @@ main(int argc, char **argv) { unsigned long long off, slimit; struct option longopts[] = { { "all", 0, 0, 'a' }, + { "set-capacity", 0, 0, 'c' }, { "detach", 0, 0, 'd' }, { "encryption", 1, 0, 'e' }, { "find", 0, 0, 'f' }, @@ -1007,7 +1022,7 @@ main(int argc, char **argv) { bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - delete = find = all = 0; + capacity = delete = find = all = 0; off = 0; slimit = 0; assoc = offset = sizelimit = encryption = passfd = NULL; @@ -1017,12 +1032,15 @@ main(int argc, char **argv) { if ((p = strrchr(progname, '/')) != NULL) progname = p+1; - while ((c = getopt_long(argc, argv, "ade:E:fhj:k:No:p:rsv", + while ((c = getopt_long(argc, argv, "acde:E:fhj:k:No:p:rsv", longopts, NULL)) != -1) { switch (c) { case 'a': all = 1; break; + case 'c': + capacity = 1; + break; case 'r': ro = 1; break; @@ -1070,16 +1088,20 @@ main(int argc, char **argv) { usage(); } else if (delete) { if (argc < optind+1 || encryption || offset || sizelimit || - find || all || showdev || assoc || ro) + capacity || find || all || showdev || assoc || ro) usage(); } else if (find) { - if (all || assoc || argc < optind || argc > optind+1) + if (capacity || all || assoc || argc < optind || argc > optind+1) usage(); } else if (all) { if (argc > 2) usage(); } else if (assoc) { - if (encryption || showdev || passfd || ro) + if (capacity || encryption || showdev || passfd || ro) + usage(); + } else if (capacity) { + if (argc != optind + 1 || encryption || offset || sizelimit || + showdev || ro) usage(); } else { if (argc < optind+1 || argc > optind+2) @@ -1118,6 +1140,8 @@ main(int argc, char **argv) { if (delete) { while (optind < argc) res += del_loop(argv[optind++]); + } else if (capacity) { + res = set_capacity(device); } else if (file == NULL) res = show_loop(device); else { diff --git a/mount/loop.h b/mount/loop.h index 60688529..64df3391 100644 --- a/mount/loop.h +++ b/mount/loop.h @@ -22,6 +22,8 @@ #define LOOP_GET_STATUS 0x4C03 #define LOOP_SET_STATUS64 0x4C04 #define LOOP_GET_STATUS64 0x4C05 +/* #define LOOP_CHANGE_FD 0x4C06 */ +#define LOOP_SET_CAPACITY 0x4C07 /* Flags for loop_into{64,}->lo_flags */ enum { diff --git a/mount/losetup.8 b/mount/losetup.8 index 11b692db..3d22b85c 100644 --- a/mount/losetup.8 +++ b/mount/losetup.8 @@ -48,7 +48,14 @@ Setup loop device: .RB [ \-r ] .RB { \-f [ \-\-show ] | \fIloopdev\fP } .I file +.sp .in -13 +Resize loop device: +.sp +.in +5 +.B "losetup \-c" +.I loopdev +.in -5 .ad b .SH DESCRIPTION .B losetup @@ -75,6 +82,8 @@ and finds the module that knows how to perform that encryption. .SH OPTIONS .IP "\fB\-a, \-\-all\fP" show status of all loop devices +.IP "\fB\-c, \-\-set-capacity\fP \fIloopdev\fP +force loop driver to reread size of the file associated with the specified loop device .IP "\fB\-d, \-\-detach\fP \fIloopdev\fP [\fIloopdev\fP ...]" detach the file or device associated with the specified loop device(s) .IP "\fB\-e, \-E, \-\-encryption \fIencryption_type\fP" @@ -134,12 +143,12 @@ from determining the status of the device. If you are using the loadable module you must have the module loaded first with the command .IP -# insmod loop.o +# modprobe loop .LP Maybe also encryption modules are needed. .IP -# insmod des.o -# insmod cryptoloop.o +# modprobe des +# modprobe cryptoloop .LP The following commands can be used as an example of using the loop device. .nf diff --git a/mount/mount.8 b/mount/mount.8 index cee784bc..0e16bfbe 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -98,7 +98,7 @@ prints a version string .BI "mount [-l] [-t" " type" ] lists all mounted file systems (of type .IR type ). -The option \-l adds the (ext2, ext3 and XFS) labels in this listing. +The option \-l adds the labels in this listing. See below. .RE @@ -409,9 +409,9 @@ exists (with regular non-fake mount, this check is done by kernel). Don't call the /sbin/mount.<filesystem> helper even if it exists. .TP .B \-l -Add the ext2, ext3 and XFS labels in the mount output. Mount must have +Add the labels in the mount output. Mount must have permission to read the disk device (e.g. be suid root) for this to work. -One can set such a label for ext2 or ext3 using the +One can set such a label for ext2, ext3 or ext4 using the .BR e2label (8) utility, or for XFS using .BR xfs_admin (8), @@ -442,10 +442,12 @@ Mount the file system read-only. A synonym is .BR "\-o ro" . Note that, depending on the filesystem type, state and kernel behavior, the -system may still write to the device. For example, Ext3 will replay its journal -if the filesystem is dirty. To prevent this kind of write access, you may want -to set the block device to read-only mode, see command -.BR blockdev (8). +system may still write to the device. For example, Ext3 or ext4 will replay its +journal if the filesystem is dirty. To prevent this kind of write access, you +may want to mount ext3 or ext4 filesystem with "ro,noload" mount options or +set the block device to read-only mode, see command +.BR blockdev (8) +. .TP .B \-w Mount the file system read/write. This is the default. A synonym is @@ -480,6 +482,7 @@ currently supported include: .IR ext , .IR ext2 , .IR ext3 , +.IR ext4 , .IR hfs , .IR hfsplus , .IR hpfs , @@ -1252,7 +1255,105 @@ manual page. Enable POSIX Access Control Lists. See the .BR acl (5) manual page. - + +.SH "Mount options for ext4" +The `ext4' is an an advanced level of the ext3 filesystem which incorporates +scalability and reliability enhancements for supporting large filesystem. + +The options +.B journal_dev, noload, data, commit, orlov, oldalloc, [no]user_xattr +.B [no]acl, bsddf, minixdf, debug, errors, data_err, grpid, bsdgroups, nogrpid +.B sysvgroups, resgid, resuid, sb, quota, noquota, grpquota, usrquota +and +.B [no]bh +are backwardly compatible with ext3 or ext2. +.TP +.BR journal_checksum +Enable checksumming of the journal transactions. This will allow the recovery +code in e2fsck and the kernel to detect corruption in the kernel. It is a +compatible change and will be ignored by older kernels. +.TP +.BR journal_async_commit +Commit block can be written to disk without waiting for descriptor blocks. If +enabled older kernels cannot mount the device. This will enable +'journal_checksum' internally. +.TP +.BR journal=update +Update the ext4 file system's journal to the current format. +.TP +.BR barrier=0 " / " barrier=1 " / " barrier " / " nobarrier +This enables/disables the use of write barriers in the jbd code. barrier=0 +disables, barrier=1 enables. This also requires an IO stack which can support +barriers, and if jbd gets an error on a barrier write, it will disable again +with a warning. Write barriers enforce proper on-disk ordering of journal +commits, making volatile disk write caches safe to use, at some performance +penalty. If your disks are battery-backed in one way or another, disabling +barriers may safely improve performance. The mount options "barrier" and +"nobarrier" can also be used to enable or disable barriers, for consistency +with other ext4 mount options. +.TP +.BI inode_readahead= n +This tuning parameter controls the maximum number of inode table blocks that +ext4's inode table readahead algorithm will pre-read into the buffer cache. +The default value is 32 blocks. +.TP +.BI stripe= n +Number of filesystem blocks that mballoc will try to use for allocation size +and alignment. For RAID5/6 systems this should be the number of data disks * +RAID chunk size in file system blocks. +.TP +.BR delalloc +Deferring block allocation until write-out time. +.TP +.BR nodelalloc +Disable delayed allocation. Blocks are allocation when data is copied from user +to page cache. +.TP +.BI max_batch_time= usec +Maximum amount of time ext4 should wait for additional filesystem operations to +be batch together with a synchronous write operation. Since a synchronous +write operation is going to force a commit and then a wait for the I/O +complete, it doesn't cost much, and can be a huge throughput win, we wait for a +small amount of time to see if any other transactions can piggyback on the +synchronous write. The algorithm used is designed to automatically tune for +the speed of the disk, by measuring the amount of time (on average) that it +takes to finish committing a transaction. Call this time the "commit time". +If the time that the transactoin has been running is less than the commit time, +ext4 will try sleeping for the commit time to see if other operations will join +the transaction. The commit time is capped by the max_batch_time, which +defaults to 15000us (15ms). This optimization can be turned off entirely by +setting max_batch_time to 0. +.TP +.BI min_batch_time= usec +This parameter sets the commit time (as described above) to be at least +min_batch_time. It defaults to zero microseconds. Increasing this parameter +may improve the throughput of multi-threaded, synchronous workloads on very +fast disks, at the cost of increasing latency. +.TP +.BI journal_ioprio= prio +The I/O priority (from 0 to 7, where 0 is the highest priorty) which should be +used for I/O operations submitted by kjournald2 during a commit operation. +This defaults to 3, which is a slightly higher priority than the default I/O +priority. +.TP +.BR auto_da_alloc " / " noauto_da_alloc +Many broken applications don't use fsync() when noauto_da_alloc +replacing existing files via patterns such as + +fd = open("foo.new")/write(fd,..)/close(fd)/ rename("foo.new", "foo") + +or worse yet + +fd = open("foo", O_TRUNC)/write(fd,..)/close(fd). + +If auto_da_alloc is enabled, ext4 will detect the replace-via-rename and +replace-via-truncate patterns and force that any delayed allocation blocks are +allocated such that at the next journal commit, in the default data=ordered +mode, the data blocks of the new file are forced to disk before the rename() +operation is commited. This provides roughly the same level of guarantees as +ext3, and avoids the "zero-length" problem that can happen when a system +crashes before the delayed allocation blocks are forced to disk. + .SH "Mount options for fat" (Note: .I fat @@ -1264,7 +1365,7 @@ and filesystems.) .TP .BR blocksize=512 " / " blocksize=1024 " / " blocksize=2048 -Set blocksize (default 512). +Set blocksize (default 512). This option is obsolete. .TP \fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP Set the owner and group of all files. @@ -1362,7 +1463,7 @@ Programs that do computed lseeks won't like in-kernel text conversion. Several people have had their data ruined by this translation. Beware! For file systems mounted in binary mode, a conversion tool -(fromdos/todos) is available. +(fromdos/todos) is available. This option is obsolete. .RE .TP .BI cvf_format= module @@ -1370,9 +1471,10 @@ Forces the driver to use the CVF (Compressed Volume File) module .RI cvf_ module instead of auto-detection. If the kernel supports kmod, the cvf_format=xxx option also controls on-demand CVF module loading. +This option is obsolete. .TP .BI cvf_option= option -Option passed to the CVF module. +Option passed to the CVF module. This option is obsolete. .TP .B debug Turn on the @@ -1691,7 +1793,7 @@ and 1 a byteswapped bigendian encoding. .B posix=[0|1] If enabled (posix=1), the file system distinguishes between upper and lower case. The 8.3 alias names are presented as -hard links instead of being suppressed. +hard links instead of being suppressed. This option is obsolete. .TP \fBuid=\fP\fIvalue\fP, \fBgid=\fP\fIvalue\fP and \fBumask=\fP\fIvalue\fP Set the file permission on the filesystem. @@ -2298,7 +2400,7 @@ One further possible type is a mount via the loop device. For example, the command .nf -.B " mount /tmp/fdimage /mnt -t msdos -o loop=/dev/loop3,blocksize=1024" +.B " mount /tmp/fdimage /mnt -t vfat -o loop=/dev/loop3 .fi will set up the loop device @@ -2323,16 +2425,16 @@ If no explicit loop device is mentioned (but just an option `\fB\-o loop\fP' is given), then .B mount will try to find some unused loop device and use that. -If you are not so unwise as to make -.I /etc/mtab -a symbolic link to -.I /proc/mounts + +Since Linux 2.6.25 is supported auto-destruction of loop devices and then any loop device allocated by .B mount will be freed by -.BR umount . -You can also free a loop device by hand, using `losetup -d', see -.BR losetup (8). +.B umount +independently on +.I /etc/mtab . + +You can also free a loop device by hand, using `losetup -d' or `umount -d`. .SH RETURN CODES .B mount diff --git a/mount/mount.c b/mount/mount.c index a43fad56..bd883391 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -907,9 +907,6 @@ guess_fstype_and_mount(const char *spec, const char *node, const char **types, if (*types && strcasecmp (*types, "auto") == 0) *types = NULL; - if (flags & (MS_BIND | MS_MOVE)) - *types = "none"; - if (!*types && !(flags & MS_REMOUNT)) { *types = guess_fstype_by_devname(spec); if (*types) { @@ -1317,6 +1314,9 @@ try_mount_one (const char *spec0, const char *node0, const char *types0, if (loop) opt_loopdev = loopdev; + if (flags & (MS_BIND | MS_MOVE | MS_PROPAGATION)) + types = "none"; + /* * Call mount.TYPE for types that require a separate mount program. * For the moment these types are ncpfs and smbfs. Maybe also vxfs. @@ -1538,6 +1538,10 @@ mount_retry: error (_("mount: %s%s is write-protected but explicit `-w' flag given"), bd, spec); break; + } else if (flags & MS_REMOUNT) { + error (_("mount: cannot remount %s%s read-write, is write-protected"), + bd, spec); + break; } else { opts = opts0; types = types0; diff --git a/mount/umount.c b/mount/umount.c index 9901a809..a695f0c6 100644 --- a/mount/umount.c +++ b/mount/umount.c @@ -14,6 +14,7 @@ #include "mount_constants.h" #include "sundries.h" #include "getusername.h" +#include "pathnames.h" #include "lomount.h" #include "loop.h" #include "fstab.h" @@ -393,9 +394,9 @@ static struct option longopts[] = static void usage (FILE *fp, int n) { - fprintf (fp, _("Usage: umount [-hV]\n" - " umount -a [-f] [-r] [-n] [-v] [-t vfstypes] [-O opts]\n" - " umount [-f] [-r] [-n] [-v] special | node...\n")); + fprintf (fp, _("Usage: umount -h | -V\n" + " umount -a [-d] [-f] [-r] [-n] [-v] [-t vfstypes] [-O opts]\n" + " umount [-d] [-f] [-r] [-n] [-v] special | node...\n")); exit (n); } @@ -406,7 +407,7 @@ static int contains(const char *list, const char *s) { int n = strlen(s); - while (*list) { + while (list && *list) { if (strncmp(list, s, n) == 0 && (list[n] == 0 || list[n] == ',')) return 1; @@ -423,7 +424,7 @@ get_value(const char *list, const char *s) { const char *t; int n = strlen(s); - while (*list) { + while (list && *list) { if (strncmp(list, s, n) == 0) { s = t = list+n; while (*s && *s != ',') @@ -432,6 +433,44 @@ get_value(const char *list, const char *s) { } while (*list && *list++ != ',') ; } + return NULL; +} + +/* check if @mc contains a loop device which is associated + * with the @file in fs + */ +static int +is_valid_loop(struct mntentchn *mc, struct mntentchn *fs) +{ + unsigned long long offset = 0; + char *p; + + /* check if it begins with /dev/loop */ + if (strncmp(mc->m.mnt_fsname, _PATH_DEV_LOOP, + sizeof(_PATH_DEV_LOOP) - 1)) + return 0; + + /* check for loop option in fstab */ + if (!contains(fs->m.mnt_opts, "loop")) + return 0; + + /* check for offset option in fstab */ + p = get_value(fs->m.mnt_opts, "offset="); + if (p) + offset = strtoull(p, NULL, 10); + + /* check association */ + if (loopfile_used_with((char *) mc->m.mnt_fsname, + fs->m.mnt_fsname, offset) == 1) { + if (verbose > 1) + printf(_("device %s is associated with %s\n"), + mc->m.mnt_fsname, fs->m.mnt_fsname); + return 1; + } + + if (verbose > 1) + printf(_("device %s is not associated with %s\n"), + mc->m.mnt_fsname, fs->m.mnt_fsname); return 0; } @@ -516,12 +555,15 @@ umount_file (char *arg) { the pair (dev,file) in fstab. */ fs = getfs_by_devdir(mc->m.mnt_fsname, mc->m.mnt_dir); if (!fs) { - if (!getfs_by_spec (file) && !getfs_by_dir (file)) + fs = getfs_by_dir(file); + if (!fs && !getfs_by_spec(file)) die (2, _("umount: %s is not in the fstab " "(and you are not root)"), file); - else + + /* spec could be a file which is loop mounted */ + if (fs && !is_valid_loop(mc, fs)) die (2, _("umount: %s mount disagrees with " "the fstab"), file); } |