Release 4.10 fs/udf/super.c
/*
* super.c
*
* PURPOSE
* Super block routines for the OSTA-UDF(tm) filesystem.
*
* DESCRIPTION
* OSTA-UDF(tm) = Optical Storage Technology Association
* Universal Disk Format.
*
* This code is based on version 2.00 of the UDF specification,
* and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
* http://www.osta.org/
* http://www.ecma.ch/
* http://www.iso.org/
*
* COPYRIGHT
* This file is distributed under the terms of the GNU General Public
* License (GPL). Copies of the GPL can be obtained from:
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
* (C) 1998 Dave Boynton
* (C) 1998-2004 Ben Fennema
* (C) 2000 Stelias Computing Inc
*
* HISTORY
*
* 09/24/98 dgb changed to allow compiling outside of kernel, and
* added some debugging.
* 10/01/98 dgb updated to allow (some) possibility of compiling w/2.0.34
* 10/16/98 attempting some multi-session support
* 10/17/98 added freespace count for "df"
* 11/11/98 gr added novrs option
* 11/26/98 dgb added fileset,anchor mount options
* 12/06/98 blf really hosed things royally. vat/sparing support. sequenced
* vol descs. rewrote option handling based on isofs
* 12/20/98 find the free space bitmap (if it exists)
*/
#include "udfdecl.h"
#include <linux/blkdev.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/parser.h>
#include <linux/stat.h>
#include <linux/cdrom.h>
#include <linux/nls.h>
#include <linux/vfs.h>
#include <linux/vmalloc.h>
#include <linux/errno.h>
#include <linux/mount.h>
#include <linux/seq_file.h>
#include <linux/bitmap.h>
#include <linux/crc-itu-t.h>
#include <linux/log2.h>
#include <asm/byteorder.h>
#include "udf_sb.h"
#include "udf_i.h"
#include <linux/init.h>
#include <linux/uaccess.h>
#define VDS_POS_PRIMARY_VOL_DESC 0
#define VDS_POS_UNALLOC_SPACE_DESC 1
#define VDS_POS_LOGICAL_VOL_DESC 2
#define VDS_POS_PARTITION_DESC 3
#define VDS_POS_IMP_USE_VOL_DESC 4
#define VDS_POS_VOL_DESC_PTR 5
#define VDS_POS_TERMINATING_DESC 6
#define VDS_POS_LENGTH 7
#define UDF_DEFAULT_BLOCKSIZE 2048
#define VSD_FIRST_SECTOR_OFFSET 32768
#define VSD_MAX_SECTOR_OFFSET 0x800000
/*
* Maximum number of Terminating Descriptor / Logical Volume Integrity
* Descriptor redirections. The chosen numbers are arbitrary - just that we
* hopefully don't limit any real use of rewritten inode on write-once media
* but avoid looping for too long on corrupted media.
*/
#define UDF_MAX_TD_NESTING 64
#define UDF_MAX_LVID_NESTING 1000
enum { UDF_MAX_LINKS = 0xffff };
/* These are the "meat" - everything else is stuffing */
static int udf_fill_super(struct super_block *, void *, int);
static void udf_put_super(struct super_block *);
static int udf_sync_fs(struct super_block *, int);
static int udf_remount_fs(struct super_block *, int *, char *);
static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *,
struct kernel_lb_addr *);
static void udf_load_fileset(struct super_block *, struct buffer_head *,
struct kernel_lb_addr *);
static void udf_open_lvid(struct super_block *);
static void udf_close_lvid(struct super_block *);
static unsigned int udf_count_free(struct super_block *);
static int udf_statfs(struct dentry *, struct kstatfs *);
static int udf_show_options(struct seq_file *, struct dentry *);
struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb)
{
struct logicalVolIntegrityDesc *lvid;
unsigned int partnum;
unsigned int offset;
if (!UDF_SB(sb)->s_lvid_bh)
return NULL;
lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data;
partnum = le32_to_cpu(lvid->numOfPartitions);
if ((sb->s_blocksize - sizeof(struct logicalVolIntegrityDescImpUse) -
offsetof(struct logicalVolIntegrityDesc, impUse)) /
(2 * sizeof(uint32_t)) < partnum) {
udf_err(sb, "Logical volume integrity descriptor corrupted "
"(numOfPartitions = %u)!\n", partnum);
return NULL;
}
/* The offset is to skip freeSpaceTable and sizeTable arrays */
offset = partnum * 2 * sizeof(uint32_t);
return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jan kara | jan kara | 85 | 61.15% | 1 | 50.00% |
marcin slusarz | marcin slusarz | 54 | 38.85% | 1 | 50.00% |
| Total | 139 | 100.00% | 2 | 100.00% |
/* UDF filesystem type */
static struct dentry *udf_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_bdev(fs_type, flags, dev_name, data, udf_fill_super);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
al viro | al viro | 33 | 84.62% | 2 | 40.00% |
pre-git | pre-git | 5 | 12.82% | 2 | 40.00% |
andries brouwer | andries brouwer | 1 | 2.56% | 1 | 20.00% |
| Total | 39 | 100.00% | 5 | 100.00% |
static struct file_system_type udf_fstype = {
.owner = THIS_MODULE,
.name = "udf",
.mount = udf_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("udf");
static struct kmem_cache *udf_inode_cachep;
static struct inode *udf_alloc_inode(struct super_block *sb)
{
struct udf_inode_info *ei;
ei = kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL);
if (!ei)
return NULL;
ei->i_unique = 0;
ei->i_lenExtents = 0;
ei->i_next_alloc_block = 0;
ei->i_next_alloc_goal = 0;
ei->i_strat4096 = 0;
init_rwsem(&ei->i_data_sem);
ei->cached_extent.lstart = -1;
spin_lock_init(&ei->i_extent_cache_lock);
return &ei->vfs_inode;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 40 | 41.67% | 1 | 20.00% |
dan bastone | dan bastone | 30 | 31.25% | 1 | 20.00% |
namjae jeon | namjae jeon | 17 | 17.71% | 1 | 20.00% |
alessio igor bogani | alessio igor bogani | 8 | 8.33% | 1 | 20.00% |
christoph lameter | christoph lameter | 1 | 1.04% | 1 | 20.00% |
| Total | 96 | 100.00% | 5 | 100.00% |
static void udf_i_callback(struct rcu_head *head)
{
struct inode *inode = container_of(head, struct inode, i_rcu);
kmem_cache_free(udf_inode_cachep, UDF_I(inode));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
nick piggin | nick piggin | 18 | 50.00% | 1 | 50.00% |
linus torvalds | linus torvalds | 18 | 50.00% | 1 | 50.00% |
| Total | 36 | 100.00% | 2 | 100.00% |
static void udf_destroy_inode(struct inode *inode)
{
call_rcu(&inode->i_rcu, udf_i_callback);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
nick piggin | nick piggin | 21 | 100.00% | 1 | 100.00% |
| Total | 21 | 100.00% | 1 | 100.00% |
static void init_once(void *foo)
{
struct udf_inode_info *ei = (struct udf_inode_info *)foo;
ei->i_ext.i_data = NULL;
inode_init_once(&ei->vfs_inode);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 27 | 71.05% | 1 | 33.33% |
al viro | al viro | 8 | 21.05% | 1 | 33.33% |
christoph lameter | christoph lameter | 3 | 7.89% | 1 | 33.33% |
| Total | 38 | 100.00% | 3 | 100.00% |
static int __init init_inodecache(void)
{
udf_inode_cachep = kmem_cache_create("udf_inode_cache",
sizeof(struct udf_inode_info),
0, (SLAB_RECLAIM_ACCOUNT |
SLAB_MEM_SPREAD |
SLAB_ACCOUNT),
init_once);
if (!udf_inode_cachep)
return -ENOMEM;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 37 | 80.43% | 1 | 14.29% |
paul jackson | paul jackson | 4 | 8.70% | 2 | 28.57% |
vladimir davydov | vladimir davydov | 2 | 4.35% | 1 | 14.29% |
fabian frederick | fabian frederick | 1 | 2.17% | 1 | 14.29% |
cyrill gorcunov | cyrill gorcunov | 1 | 2.17% | 1 | 14.29% |
andrew morton | andrew morton | 1 | 2.17% | 1 | 14.29% |
| Total | 46 | 100.00% | 7 | 100.00% |
static void destroy_inodecache(void)
{
/*
* Make sure all delayed rcu free inodes are flushed before we
* destroy cache.
*/
rcu_barrier();
kmem_cache_destroy(udf_inode_cachep);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 13 | 76.47% | 1 | 50.00% |
kirill a. shutemov | kirill a. shutemov | 4 | 23.53% | 1 | 50.00% |
| Total | 17 | 100.00% | 2 | 100.00% |
/* Superblock operations */
static const struct super_operations udf_sb_ops = {
.alloc_inode = udf_alloc_inode,
.destroy_inode = udf_destroy_inode,
.write_inode = udf_write_inode,
.evict_inode = udf_evict_inode,
.put_super = udf_put_super,
.sync_fs = udf_sync_fs,
.statfs = udf_statfs,
.remount_fs = udf_remount_fs,
.show_options = udf_show_options,
};
struct udf_options {
unsigned char novrs;
unsigned int blocksize;
unsigned int session;
unsigned int lastblock;
unsigned int anchor;
unsigned int volume;
unsigned short partition;
unsigned int fileset;
unsigned int rootdir;
unsigned int flags;
umode_t umask;
kgid_t gid;
kuid_t uid;
umode_t fmode;
umode_t dmode;
struct nls_table *nls_map;
};
static int __init init_udf_fs(void)
{
int err;
err = init_inodecache();
if (err)
goto out1;
err = register_filesystem(&udf_fstype);
if (err)
goto out;
return 0;
out:
destroy_inodecache();
out1:
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 37 | 71.15% | 1 | 33.33% |
pre-git | pre-git | 15 | 28.85% | 2 | 66.67% |
| Total | 52 | 100.00% | 3 | 100.00% |
static void __exit exit_udf_fs(void)
{
unregister_filesystem(&udf_fstype);
destroy_inodecache();
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 15 | 83.33% | 2 | 66.67% |
linus torvalds | linus torvalds | 3 | 16.67% | 1 | 33.33% |
| Total | 18 | 100.00% | 3 | 100.00% |
module_init(init_udf_fs)
module_exit(exit_udf_fs)
static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count)
{
struct udf_sb_info *sbi = UDF_SB(sb);
sbi->s_partmaps = kcalloc(count, sizeof(struct udf_part_map),
GFP_KERNEL);
if (!sbi->s_partmaps) {
udf_err(sb, "Unable to allocate space for %d partition maps\n",
count);
sbi->s_partitions = 0;
return -ENOMEM;
}
sbi->s_partitions = count;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
marcin slusarz | marcin slusarz | 75 | 96.15% | 1 | 33.33% |
joe perches | joe perches | 2 | 2.56% | 1 | 33.33% |
andrew morton | andrew morton | 1 | 1.28% | 1 | 33.33% |
| Total | 78 | 100.00% | 3 | 100.00% |
static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
{
int i;
int nr_groups = bitmap->s_nr_groups;
for (i = 0; i < nr_groups; i++)
if (bitmap->s_block_bitmap[i])
brelse(bitmap->s_block_bitmap[i]);
kvfree(bitmap);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jan kara | jan kara | 57 | 98.28% | 1 | 50.00% |
tetsuo handa | tetsuo handa | 1 | 1.72% | 1 | 50.00% |
| Total | 58 | 100.00% | 2 | 100.00% |
static void udf_free_partition(struct udf_part_map *map)
{
int i;
struct udf_meta_data *mdata;
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
iput(map->s_uspace.s_table);
if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
iput(map->s_fspace.s_table);
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
udf_sb_free_bitmap(map->s_uspace.s_bitmap);
if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
udf_sb_free_bitmap(map->s_fspace.s_bitmap);
if (map->s_partition_type == UDF_SPARABLE_MAP15)
for (i = 0; i < 4; i++)
brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
else if (map->s_partition_type == UDF_METADATA_MAP25) {
mdata = &map->s_type_specific.s_metadata;
iput(mdata->s_metadata_fe);
mdata->s_metadata_fe = NULL;
iput(mdata->s_mirror_fe);
mdata->s_mirror_fe = NULL;
iput(mdata->s_bitmap_fe);
mdata->s_bitmap_fe = NULL;
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jan kara | jan kara | 181 | 100.00% | 1 | 100.00% |
| Total | 181 | 100.00% | 1 | 100.00% |
static void udf_sb_free_partitions(struct super_block *sb)
{
struct udf_sb_info *sbi = UDF_SB(sb);
int i;
if (sbi->s_partmaps == NULL)
return;
for (i = 0; i < sbi->s_partitions; i++)
udf_free_partition(&sbi->s_partmaps[i]);
kfree(sbi->s_partmaps);
sbi->s_partmaps = NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jan kara | jan kara | 63 | 87.50% | 1 | 50.00% |
namjae jeon | namjae jeon | 9 | 12.50% | 1 | 50.00% |
| Total | 72 | 100.00% | 2 | 100.00% |
static int udf_show_options(struct seq_file *seq, struct dentry *root)
{
struct super_block *sb = root->d_sb;
struct udf_sb_info *sbi = UDF_SB(sb);
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT))
seq_puts(seq, ",nostrict");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET))
seq_printf(seq, ",bs=%lu", sb->s_blocksize);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE))
seq_puts(seq, ",unhide");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE))
seq_puts(seq, ",undelete");
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_USE_AD_IN_ICB))
seq_puts(seq, ",noadinicb");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_USE_SHORT_AD))
seq_puts(seq, ",shortad");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_FORGET))
seq_puts(seq, ",uid=forget");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_IGNORE))
seq_puts(seq, ",uid=ignore");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_FORGET))
seq_puts(seq, ",gid=forget");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_IGNORE))
seq_puts(seq, ",gid=ignore");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET))
seq_printf(seq, ",uid=%u", from_kuid(&init_user_ns, sbi->s_uid));
if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
seq_printf(seq, ",gid=%u", from_kgid(&init_user_ns, sbi->s_gid));
if (sbi->s_umask != 0)
seq_printf(seq, ",umask=%ho", sbi->s_umask);
if (sbi->s_fmode != UDF_INVALID_MODE)
seq_printf(seq, ",mode=%ho", sbi->s_fmode);
if (sbi->s_dmode != UDF_INVALID_MODE)
seq_printf(seq, ",dmode=%ho", sbi->s_dmode);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
seq_printf(seq, ",session=%u", sbi->s_session);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
seq_printf(seq, ",lastblock=%u", sbi->s_last_block);
if (sbi->s_anchor != 0)
seq_printf(seq, ",anchor=%u", sbi->s_anchor);
/*
* volume, partition, fileset and rootdir seem to be ignored
* currently
*/
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
seq_puts(seq, ",utf8");
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP) && sbi->s_nls_map)
seq_printf(seq, ",iocharset=%s", sbi->s_nls_map->charset);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
miklos szeredi | miklos szeredi | 355 | 85.54% | 1 | 14.29% |
marcin slusarz | marcin slusarz | 36 | 8.67% | 2 | 28.57% |
eric w. biederman | eric w. biederman | 12 | 2.89% | 1 | 14.29% |
al viro | al viro | 7 | 1.69% | 2 | 28.57% |
clemens ladisch | clemens ladisch | 5 | 1.20% | 1 | 14.29% |
| Total | 415 | 100.00% | 7 | 100.00% |
/*
* udf_parse_options
*
* PURPOSE
* Parse mount options.
*
* DESCRIPTION
* The following mount options are supported:
*
* gid= Set the default group.
* umask= Set the default umask.
* mode= Set the default file permissions.
* dmode= Set the default directory permissions.
* uid= Set the default user.
* bs= Set the block size.
* unhide Show otherwise hidden files.
* undelete Show deleted files in lists.
* adinicb Embed data in the inode (default)
* noadinicb Don't embed data in the inode
* shortad Use short ad's
* longad Use long ad's (default)
* nostrict Unset strict conformance
* iocharset= Set the NLS character set
*
* The remaining are for debugging and disaster recovery:
*
* novrs Skip volume sequence recognition
*
* The following expect a offset from 0.
*
* session= Set the CDROM session (default= last session)
* anchor= Override standard anchor location. (default= 256)
* volume= Override the VolumeDesc location. (unused)
* partition= Override the PartitionDesc location. (unused)
* lastblock= Set the last block of the filesystem/
*
* The following expect a offset from the partition root.
*
* fileset= Override the fileset block location. (unused)
* rootdir= Override the root directory location. (unused)
* WARNING: overriding the rootdir to a non-directory may
* yield highly unpredictable results.
*
* PRE-CONDITIONS
* options Pointer to mount options string.
* uopts Pointer to mount options variable.
*
* POST-CONDITIONS
* <return> 1 Mount options parsed okay.
* <return> 0 Error parsing mount options.
*
* HISTORY
* July 1, 1997 - Andrew E. Mileski
* Written, tested, and released.
*/
enum {
Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
Opt_rootdir, Opt_utf8, Opt_iocharset,
Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore,
Opt_fmode, Opt_dmode
};
static const match_table_t tokens = {
{Opt_novrs, "novrs"},
{Opt_nostrict, "nostrict"},
{Opt_bs, "bs=%u"},
{Opt_unhide, "unhide"},
{Opt_undelete, "undelete"},
{Opt_noadinicb, "noadinicb"},
{Opt_adinicb, "adinicb"},
{Opt_shortad, "shortad"},
{Opt_longad, "longad"},
{Opt_uforget, "uid=forget"},
{Opt_uignore, "uid=ignore"},
{Opt_gforget, "gid=forget"},
{Opt_gignore, "gid=ignore"},
{Opt_gid, "gid=%u"},
{Opt_uid, "uid=%u"},
{Opt_umask, "umask=%o"},
{Opt_session, "session=%u"},
{Opt_lastblock, "lastblock=%u"},
{Opt_anchor, "anchor=%u"},
{Opt_volume, "volume=%u"},
{Opt_partition, "partition=%u"},
{Opt_fileset, "fileset=%u"},
{Opt_rootdir, "rootdir=%u"},
{Opt_utf8, "utf8"},
{Opt_iocharset, "iocharset=%s"},
{Opt_fmode, "mode=%o"},
{Opt_dmode, "dmode=%o"},
{Opt_err, NULL}
};
static int udf_parse_options(char *options, struct udf_options *uopt,
bool remount)
{
char *p;
int option;
uopt->novrs = 0;
uopt->partition = 0xFFFF;
uopt->session = 0xFFFFFFFF;
uopt->lastblock = 0;
uopt->anchor = 0;
uopt->volume = 0xFFFFFFFF;
uopt->rootdir = 0xFFFFFFFF;
uopt->fileset = 0xFFFFFFFF;
uopt->nls_map = NULL;
if (!options)
return 1;
while ((p = strsep(&options, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
int token;
unsigned n;
if (!*p)
continue;
token = match_token(p, tokens, args);
switch (token) {
case Opt_novrs:
uopt->novrs = 1;
break;
case Opt_bs:
if (match_int(&args[0], &option))
return 0;
n = option;
if (n != 512 && n != 1024 && n != 2048 && n != 4096)
return 0;
uopt->blocksize = n;
uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET);
break;
case Opt_unhide:
uopt->flags |= (1 << UDF_FLAG_UNHIDE);
break;
case Opt_undelete:
uopt->flags |= (1 << UDF_FLAG_UNDELETE);
break;
case Opt_noadinicb:
uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
break;
case Opt_adinicb:
uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
break;
case Opt_shortad:
uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
break;
case Opt_longad:
uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
break;
case Opt_gid:
if (match_int(args, &option))
return 0;
uopt->gid = make_kgid(current_user_ns(), option);
if (!gid_valid(uopt->gid))
return 0;
uopt->flags |= (1 << UDF_FLAG_GID_SET);
break;
case Opt_uid:
if (match_int(args, &option))
return 0;
uopt->uid = make_kuid(current_user_ns(), option);
if (!uid_valid(uopt->uid))
return 0;
uopt->flags |= (1 << UDF_FLAG_UID_SET);
break;
case Opt_umask:
if (match_octal(args, &option))
return 0;
uopt->umask = option;
break;
case Opt_nostrict:
uopt->flags &= ~(1 << UDF_FLAG_STRICT);
break;
case Opt_session:
if (match_int(args, &option))
return 0;
uopt->session = option;
if (!remount)
uopt->flags |= (1 << UDF_FLAG_SESSION_SET);
break;
case Opt_lastblock:
if (match_int(args, &option))
return 0;
uopt->lastblock = option;
if (!remount)
uopt->flags |= (1 << UDF_FLAG_LASTBLOCK_SET);
break;
case Opt_anchor:
if (match_int(args, &option))
return 0;
uopt->anchor = option;
break;
case Opt_volume:
if (match_int(args, &option))
return 0;
uopt->volume = option;
break;
case Opt_partition:
if (match_int(args, &option))
return 0;
uopt->partition = option;
break;
case Opt_fileset:
if (match_int(args, &option))
return 0;
uopt->fileset = option;
break;
case Opt_rootdir:
if (match_int(args, &option))
return 0;
uopt->rootdir = option;
break;
case Opt_utf8:
uopt->flags |= (1 << UDF_FLAG_UTF8);
break;
#ifdef CONFIG_UDF_NLS
case Opt_iocharset:
uopt->nls_map = load_nls(args[0].from);
uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
break;
#endif
case Opt_uignore:
uopt->flags |= (1 << UDF_FLAG_UID_IGNORE);
break;
case Opt_uforget:
uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
break;
case Opt_gignore:
uopt->flags |= (1 << UDF_FLAG_GID_IGNORE);
break;
case Opt_gforget:
uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
break;
case Opt_fmode:
if (match_octal(args, &option))
return 0;
uopt->fmode = option & 0777;
break;
case Opt_dmode:
if (match_octal(args, &option))
return 0;
uopt->dmode = option & 0777;
break;
default:
pr_err("bad mount option \"%s\" or missing value\n", p);
return 0;
}
}
return 1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 292 | 36.55% | 2 | 11.76% |
andrew morton | andrew morton | 221 | 27.66% | 1 | 5.88% |
phillip susi | phillip susi | 56 | 7.01% | 1 | 5.88% |
marcin slusarz | marcin slusarz | 50 | 6.26% | 1 | 5.88% |
linus torvalds | linus torvalds | 44 | 5.51% | 4 | 23.53% |
eric w. biederman | eric w. biederman | 38 | 4.76% | 1 | 5.88% |
miklos szeredi | miklos szeredi | 33 | 4.13% | 1 | 5.88% |
fabian frederick | fabian frederick | 29 | 3.63% | 1 | 5.88% |
cyrill gorcunov | cyrill gorcunov | 20 | 2.50% | 1 | 5.88% |
clemens ladisch | clemens ladisch | 11 | 1.38% | 2 | 11.76% |
adrian bunk | adrian bunk | 3 | 0.38% | 1 | 5.88% |
joe perches | joe perches | 2 | 0.25% | 1 | 5.88% |
| Total | 799 | 100.00% | 17 | 100.00% |
static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
{
struct udf_options uopt;
struct udf_sb_info *sbi = UDF_SB(sb);
int error = 0;
struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb);
sync_filesystem(sb);
if (lvidiu) {
int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY))
return -EACCES;
}
uopt.flags = sbi->s_flags;
uopt.uid = sbi->s_uid;
uopt.gid = sbi->s_gid;
uopt.umask = sbi->s_umask;
uopt.fmode = sbi->s_fmode;
uopt.dmode = sbi->s_dmode;
if (!udf_parse_options(options, &uopt, true))
return -EINVAL;
write_lock(&sbi->s_cred_lock);
sbi->s_flags = uopt.flags;
sbi->s_uid = uopt.uid;
sbi->s_gid = uopt.gid;
sbi->s_umask = uopt.umask;
sbi->s_fmode = uopt.fmode;
sbi->s_dmode = uopt.dmode;
write_unlock(&sbi->