VERSION = 3
PATCHLEVEL = 3
SUBLEVEL = 0
- EXTRAVERSION = -rc4
+ EXTRAVERSION = -rc5
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
KBUILD_CHECKSRC = 0
endif
+# Call message checker as part of the C compilation
+#
+# Use 'make D=1' to enable checking
+# Use 'make D=2' to create the message catalog
+
+ifdef D
+ ifeq ("$(origin D)", "command line")
+ KBUILD_KMSG_CHECK = $(D)
+ endif
+endif
+ifndef KBUILD_KMSG_CHECK
+ KBUILD_KMSG_CHECK = 0
+endif
+
# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-Wbitwise -Wno-return-void $(CF)
+KMSG_CHECK = $(srctree)/scripts/kmsg-doc
CFLAGS_MODULE =
AFLAGS_MODULE =
LDFLAGS_MODULE =
KBUILD_CFLAGS_MODULE := -DMODULE
KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
+# Warn about unsupported modules in kernels built inside Autobuild
+ifneq ($(wildcard /.buildenv),)
+CFLAGS += -DUNSUPPORTED_MODULES=2
+endif
+
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
export KBUILD_ARFLAGS
+export KBUILD_KMSG_CHECK KMSG_CHECK
# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
endif
endif
+ifdef CONFIG_UNWIND_INFO
+KBUILD_CFLAGS += -fasynchronous-unwind-tables
+LDFLAGS_vmlinux += --eh-frame-hdr
+endif
+
ifdef CONFIG_DEBUG_INFO
KBUILD_CFLAGS += -g
KBUILD_AFLAGS += -gdwarf-2
# ---------------------------------------------------------------------------
# Firmware install
-INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware
+INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware/$(KERNELRELEASE)
export INSTALL_FW_PATH
PHONY += firmware_install
#include <linux/types.h>
#include <linux/version.h>
+ #include <asm-generic/io-64-nonatomic-lo-hi.h>
+
#define NVME_Q_DEPTH 1024
#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command))
#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion))
writel(0, &dev->bar->cc);
writel(aqa, &dev->bar->aqa);
+ /* These are not defined on all archs */
writeq(nvmeq->sq_dma_addr, &dev->bar->asq);
writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
writel(dev->ctrl_config, &dev->bar->cc);
* and displaying garbage for the Vendor, Product, or Revision
* strings.
*/
- if (sdev->inquiry_len < 36) {
+ if (sdev->inquiry_len < 36 && printk_ratelimit()) {
printk(KERN_INFO "scsi scan: INQUIRY result too short (%d),"
" using 36\n", sdev->inquiry_len);
sdev->inquiry_len = 36;
}
spin_unlock(&async_scan_lock);
+ scsi_autopm_put_host(shost);
scsi_host_put(shost);
kfree(data);
}
do_scsi_scan_host(shost);
scsi_finish_async_scan(data);
- scsi_autopm_put_host(shost);
return 0;
}
p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
if (IS_ERR(p))
do_scan_async(data);
- /* scsi_autopm_put_host(shost) is called in do_scan_async() */
+ /* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */
}
EXPORT_SYMBOL(scsi_scan_host);
struct dentry *old;
/* Don't create child dentry for a dead directory. */
- if (unlikely(IS_DEADDIR(inode)))
+ if (unlikely(IS_DEADDIR(inode))) {
+ dput(dentry);
return ERR_PTR(-ENOENT);
+ }
old = inode->i_op->lookup(inode, dentry, nd);
if (unlikely(old)) {
}
/*
+ * Do the directory specific tests of inode_permission() and call the
+ * may_delete inode operation. The may_delete inode operation must do the
+ * sticky check when needed.
+ */
+static int may_delete_iop(struct inode *dir, struct inode *inode, int replace)
+{
+ int error;
+
+ if (IS_RDONLY(dir))
+ return -EROFS;
+ if (IS_IMMUTABLE(dir))
+ return -EACCES;
+ error = dir->i_op->may_delete(dir, inode, replace);
+ if (!error)
+ error = security_inode_permission(dir, MAY_WRITE | MAY_EXEC);
+
+ return error;
+}
+
+/*
* Check whether we can remove a link victim from directory dir, check
* whether the type of victim is right.
* 1. We can't do it if dir is read-only (done in permission())
* 10. We don't allow removal of NFS sillyrenamed files; it's handled by
* nfs_async_unlink().
*/
-static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
+static int may_delete(struct inode *dir, struct dentry *victim,
+ int isdir, int replace)
{
int error;
BUG_ON(victim->d_parent->d_inode != dir);
audit_inode_child(victim, dir);
-
- error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
+ if (dir->i_op->may_delete)
+ error = may_delete_iop(dir, victim->d_inode, replace);
+ else {
+ error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
+ if (!error && check_sticky(dir, victim->d_inode))
+ error = -EPERM;
+ }
if (error)
return error;
if (IS_APPEND(dir))
return -EPERM;
- if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
- IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
+ if (IS_APPEND(victim->d_inode) || IS_IMMUTABLE(victim->d_inode) ||
+ IS_SWAPFILE(victim->d_inode))
return -EPERM;
if (isdir) {
if (!S_ISDIR(victim->d_inode->i_mode))
return 0;
}
+/*
+ * Do the directory specific tests of inode_permission() and call the
+ * may_create inode operation.
+ */
+static int may_create_iop(struct inode *dir, int isdir)
+{
+ int error;
+
+ if (IS_RDONLY(dir))
+ return -EROFS;
+ if (IS_IMMUTABLE(dir))
+ return -EACCES;
+ error = dir->i_op->may_create(dir, isdir);
+ if (!error)
+ error = security_inode_permission(dir, MAY_WRITE | MAY_EXEC);
+
+ return error;
+}
+
/* Check whether we can create an object with dentry child in directory
* dir.
* 1. We can't do it if child already exists (open has special treatment for
* 3. We should have write and exec permissions on dir
* 4. We can't do it if dir is immutable (done in permission())
*/
-static inline int may_create(struct inode *dir, struct dentry *child)
+static inline int may_create(struct inode *dir, struct dentry *child, int isdir)
{
if (child->d_inode)
return -EEXIST;
if (IS_DEADDIR(dir))
return -ENOENT;
- return inode_permission(dir, MAY_WRITE | MAY_EXEC);
+ if (dir->i_op->may_create)
+ return may_create_iop(dir, isdir);
+ else
+ return inode_permission(dir, MAY_WRITE | MAY_EXEC);
}
/*
int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
struct nameidata *nd)
{
- int error = may_create(dir, dentry);
+ int error = may_create(dir, dentry, 0);
if (error)
return error;
/* Negative dentry, just create the file */
if (!dentry->d_inode) {
umode_t mode = op->mode;
- if (!IS_POSIXACL(dir->d_inode))
+ if (!IS_ACL(dir->d_inode))
mode &= ~current_umask();
/*
* This write is needed to ensure that a
int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
{
- int error = may_create(dir, dentry);
+ int error = may_create(dir, dentry, 0);
if (error)
return error;
if (IS_ERR(dentry))
return PTR_ERR(dentry);
- if (!IS_POSIXACL(path.dentry->d_inode))
+ if (!IS_ACL(path.dentry->d_inode))
mode &= ~current_umask();
error = may_mknod(mode);
if (error)
int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
- int error = may_create(dir, dentry);
+ int error = may_create(dir, dentry, 1);
if (error)
return error;
if (IS_ERR(dentry))
return PTR_ERR(dentry);
- if (!IS_POSIXACL(path.dentry->d_inode))
+ if (!IS_ACL(path.dentry->d_inode))
mode &= ~current_umask();
error = mnt_want_write(path.mnt);
if (error)
int vfs_rmdir(struct inode *dir, struct dentry *dentry)
{
- int error = may_delete(dir, dentry, 1);
+ int error = may_delete(dir, dentry, 1, 0);
if (error)
return error;
int vfs_unlink(struct inode *dir, struct dentry *dentry)
{
- int error = may_delete(dir, dentry, 0);
+ int error = may_delete(dir, dentry, 0, 0);
if (error)
return error;
int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
{
- int error = may_create(dir, dentry);
+ int error = may_create(dir, dentry, 0);
if (error)
return error;
if (!inode)
return -ENOENT;
- error = may_create(dir, new_dentry);
+ error = may_create(dir, new_dentry, S_ISDIR(inode->i_mode));
if (error)
return error;
if (old_dentry->d_inode == new_dentry->d_inode)
return 0;
- error = may_delete(old_dir, old_dentry, is_dir);
+ error = may_delete(old_dir, old_dentry, is_dir, 0);
if (error)
return error;
if (!new_dentry->d_inode)
- error = may_create(new_dir, new_dentry);
+ error = may_create(new_dir, new_dentry, is_dir);
else
- error = may_delete(new_dir, new_dentry, is_dir);
+ error = may_delete(new_dir, new_dentry, is_dir, 1);
if (error)
return error;
EXPORT_SYMBOL(get_super);
/**
+ * get_super_thawed - get thawed superblock of a device
+ * @bdev: device to get the superblock for
+ *
+ * Scans the superblock list and finds the superblock of the file system
+ * mounted on the device. The superblock is returned once it is thawed
+ * (or immediately if it was not frozen). %NULL is returned if no match
+ * is found.
+ */
+ struct super_block *get_super_thawed(struct block_device *bdev)
+ {
+ while (1) {
+ struct super_block *s = get_super(bdev);
+ if (!s || s->s_frozen == SB_UNFROZEN)
+ return s;
+ up_read(&s->s_umount);
+ vfs_check_frozen(s, SB_FREEZE_WRITE);
+ put_super(s);
+ }
+ }
+ EXPORT_SYMBOL(get_super_thawed);
+
+ /**
* get_active_super - get an active reference to the superblock of a device
* @bdev: device to get the superblock for
*
return NULL;
}
-/**
- * do_remount_sb - asks filesystem to change mount options.
- * @sb: superblock in question
- * @flags: numeric part of options
- * @data: the rest of options
- * @force: whether or not to force the change
- *
- * Alters the mount options of a mounted file system.
- */
-int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
+#define REMOUNT_FORCE 1
+#define REMOUNT_SHRINK_DCACHE 2
+
+static int __do_remount_sb(struct super_block *sb, int flags, void *data, int rflags)
{
int retval;
int remount_ro;
if (flags & MS_RDONLY)
acct_auto_close(sb);
- shrink_dcache_sb(sb);
+ if (rflags & REMOUNT_SHRINK_DCACHE)
+ shrink_dcache_sb(sb);
sync_filesystem(sb);
remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
/* If we are remounting RDONLY and current sb is read/write,
make sure there are no rw files opened */
if (remount_ro) {
- if (force) {
+ if (rflags & REMOUNT_FORCE) {
mark_files_ro(sb);
} else {
retval = sb_prepare_remount_readonly(sb);
if (sb->s_op->remount_fs) {
retval = sb->s_op->remount_fs(sb, &flags, data);
if (retval) {
- if (!force)
+ if (!(rflags & REMOUNT_FORCE))
goto cancel_readonly;
/* If forced remount, go ahead despite any errors */
WARN(1, "forced remount of a %s fs returned %i\n",
return retval;
}
+/**
+ * do_remount_sb - asks filesystem to change mount options.
+ * @sb: superblock in question
+ * @flags: numeric part of options
+ * @data: the rest of options
+ * @force: whether or not to force the change
+ *
+ * Alters the mount options of a mounted file system.
+ */
+int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
+{
+ return __do_remount_sb(sb, flags, data,
+ REMOUNT_SHRINK_DCACHE|(force? REMOUNT_FORCE : 0));
+}
+
static void do_emergency_remount(struct work_struct *work)
{
struct super_block *sb, *p = NULL;
}
s->s_flags |= MS_ACTIVE;
} else {
- do_remount_sb(s, flags, data, 0);
+ __do_remount_sb(s, flags, data, 0);
}
return dget(s->s_root);
}
#define MS_VERBOSE 32768 /* War is peace. Verbosity is silence.
MS_VERBOSE is deprecated. */
#define MS_SILENT 32768
-#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
+#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */
#define MS_UNBINDABLE (1<<17) /* change to unbindable */
#define MS_PRIVATE (1<<18) /* change to private */
#define MS_SLAVE (1<<19) /* change to slave */
#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
#define MS_I_VERSION (1<<23) /* Update inode I_version field */
#define MS_STRICTATIME (1<<24) /* Always perform atime updates */
+#define MS_RICHACL (1<<25) /* Supports richacls */
#define MS_NOSEC (1<<28)
#define MS_BORN (1<<29)
#define MS_ACTIVE (1<<30)
#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
+#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL)
#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
#define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT)
#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
+/*
+ * IS_ACL() tells the VFS to not apply the umask
+ * and use iop->check_acl for acl permission checks when defined.
+ */
+#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | MS_RICHACL)
+
/* the read-only stuff doesn't really belong here, but any other place is
probably as bad and I don't want to create yet another include file. */
void (*truncate_range)(struct inode *, loff_t, loff_t);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
+ int (*may_create) (struct inode *, int);
+ int (*may_delete) (struct inode *, struct inode *, int);
+
+
} ____cacheline_aligned;
struct seq_file;
extern void put_filesystem(struct file_system_type *fs);
extern struct file_system_type *get_fs_type(const char *name);
extern struct super_block *get_super(struct block_device *);
+ extern struct super_block *get_super_thawed(struct block_device *);
extern struct super_block *get_active_super(struct block_device *bdev);
extern void drop_super(struct super_block *sb);
extern void iterate_supers(void (*)(struct super_block *, void *), void *);
va_end(args);
}
- pr_warn("%s: page allocation failure: order:%d, mode:0x%x\n",
+ if (!(gfp_mask & __GFP_WAIT)) {
+ pr_info("The following is only an harmless informational message.\n");
+ pr_info("Unless you get a _continuous_flood_ of these messages it means\n");
+ pr_info("everything is working fine. Allocations from irqs cannot be\n");
+ pr_info("perfectly reliable and the kernel is designed to handle that.\n");
+ }
+ pr_info("%s: page allocation failure. order:%d, mode:0x%x\n",
current->comm, order, gfp_mask);
dump_stack();
max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
do_div(max, bucketsize);
}
+ max = min(max, 0x80000000ULL);
if (numentries > max)
numentries = max;
return 0;
}
+ #ifndef R_ARM_CALL
+ #define R_ARM_CALL 28
+ #endif
+ #ifndef R_ARM_JUMP24
+ #define R_ARM_JUMP24 29
+ #endif
+
static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
{
unsigned int r_typ = ELF_R_TYPE(r->r_info);
(elf->symtab_start + ELF_R_SYM(r->r_info));
break;
case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
/* From ARM ABI: ((S + A) | T) - P */
r->r_addend = (int)(long)(elf->hdr +
sechdr->sh_offset +
}
}
+void *supported_file;
+unsigned long supported_size;
+
+static const char *supported(struct module *mod)
+{
+ unsigned long pos = 0;
+ char *line;
+
+ /* In a first shot, do a simple linear scan. */
+ while ((line = get_next_line(&pos, supported_file,
+ supported_size))) {
+ const char *basename, *how = "yes";
+ char *l = line;
+
+ /* optional type-of-support flag */
+ for (l = line; *l != '\0'; l++) {
+ if (*l == ' ' || *l == '\t') {
+ *l = '\0';
+ how = l + 1;
+ break;
+ }
+ }
+
+ /* skip directory components */
+ if ((l = strrchr(line, '/')))
+ line = l + 1;
+ /* strip .ko extension */
+ l = line + strlen(line);
+ if (l - line > 3 && !strcmp(l-3, ".ko"))
+ *(l-3) = '\0';
+
+ /* skip directory components */
+ if ((basename = strrchr(mod->name, '/')))
+ basename++;
+ else
+ basename = mod->name;
+ if (!strcmp(basename, line))
+ return how;
+ }
+ return NULL;
+}
+
static void read_symbols(char *modname)
{
const char *symname;
buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
}
+static void add_supported_flag(struct buffer *b, struct module *mod)
+{
+ const char *how = supported(mod);
+ if (how)
+ buf_printf(b, "\nMODULE_INFO(supported, \"%s\");\n", how);
+}
+
/**
* Record CRCs for unresolved symbols
**/
fclose(file);
}
+static void read_supported(const char *fname)
+{
+ supported_file = grab_file(fname, &supported_size);
+ if (!supported_file)
+ ; /* ignore error */
+}
+
/* parse Module.symvers file. line format:
* 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
**/
struct buffer buf = { };
char *kernel_read = NULL, *module_read = NULL;
char *dump_write = NULL;
+ const char *supported = NULL;
int opt;
int err;
struct ext_sym_list *extsym_iter;
struct ext_sym_list *extsym_start = NULL;
- while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:")) != -1) {
+ while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:N:")) != -1) {
switch (opt) {
case 'i':
kernel_read = optarg;
case 'w':
warn_unresolved = 1;
break;
+ case 'N':
+ supported = optarg;
+ break;
default:
exit(1);
}
}
+ if (supported)
+ read_supported(supported);
if (kernel_read)
read_dump(kernel_read, 1);
if (module_read)
add_header(&buf, mod);
add_intree_flag(&buf, !external_module);
add_staging_flag(&buf, mod->name);
+ add_supported_flag(&buf, mod);
err |= add_versions(&buf, mod);
add_depends(&buf, mod, modules);
add_moddevtable(&buf, mod);