diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fat/dir.c | 11 | ||||
-rw-r--r-- | fs/fat/inode.c | 5 | ||||
-rw-r--r-- | fs/fs-writeback.c | 2 | ||||
-rw-r--r-- | fs/fuse/dev.c | 6 | ||||
-rw-r--r-- | fs/proc/base.c | 37 |
5 files changed, 58 insertions, 3 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 3963ede84eb0..a0a029f560c7 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -780,6 +780,13 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *file, return ret; } +static int fat_ioctl_volume_id(struct inode *dir) +{ + struct super_block *sb = dir->i_sb; + struct msdos_sb_info *sbi = MSDOS_SB(sb); + return sbi->vol_id; +} + static long fat_dir_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -796,6 +803,8 @@ static long fat_dir_ioctl(struct file *filp, unsigned int cmd, short_only = 0; both = 1; break; + case VFAT_IOCTL_GET_VOLUME_ID: + return fat_ioctl_volume_id(inode); default: return fat_generic_ioctl(filp, cmd, arg); } @@ -836,6 +845,8 @@ static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd, short_only = 0; both = 1; break; + case VFAT_IOCTL_GET_VOLUME_ID: + return fat_ioctl_volume_id(inode); default: return fat_generic_ioctl(filp, cmd, (unsigned long)arg); } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 0062da21dd8b..baa0a1745791 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1252,6 +1252,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, struct inode *fsinfo_inode = NULL; struct buffer_head *bh; struct fat_boot_sector *b; + struct fat_boot_bsx *bsx; struct msdos_sb_info *sbi; u16 logical_sector_size; u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors; @@ -1398,6 +1399,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, goto out_fail; } + bsx = (struct fat_boot_bsx *)(bh->b_data + FAT32_BSX_OFFSET); + fsinfo = (struct fat_boot_fsinfo *)fsinfo_bh->b_data; if (!IS_FSINFO(fsinfo)) { fat_msg(sb, KERN_WARNING, "Invalid FSINFO signature: " @@ -1413,6 +1416,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, } brelse(fsinfo_bh); + } else { + bsx = (struct fat_boot_bsx *)(bh->b_data + FAT16_BSX_OFFSET); } /* interpret volume ID as a little endian 32 bit integer */ diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 9f4935b8f208..0fa8baba7e7f 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1137,7 +1137,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) if ((inode->i_state & flags) == flags) return; - if (unlikely(block_dump)) + if (unlikely(block_dump > 1)) block_dump___mark_inode_dirty(inode); spin_lock(&inode->i_lock); diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ef74ad5fd362..5ebb592b18bd 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -20,6 +20,7 @@ #include <linux/swap.h> #include <linux/splice.h> #include <linux/aio.h> +#include <linux/freezer.h> MODULE_ALIAS_MISCDEV(FUSE_MINOR); MODULE_ALIAS("devname:fuse"); @@ -464,7 +465,10 @@ __acquires(fc->lock) * Wait it out. */ spin_unlock(&fc->lock); - wait_event(req->waitq, req->state == FUSE_REQ_FINISHED); + + while (req->state != FUSE_REQ_FINISHED) + wait_event_freezable(req->waitq, + req->state == FUSE_REQ_FINISHED); spin_lock(&fc->lock); if (!req->aborted) diff --git a/fs/proc/base.c b/fs/proc/base.c index 1485e38daaa3..3e177c7f2328 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -139,6 +139,12 @@ struct pid_entry { NULL, &proc_single_file_operations, \ { .proc_show = show } ) +/* ANDROID is for special files in /proc. */ +#define ANDROID(NAME, MODE, OTYPE) \ + NOD(NAME, (S_IFREG|(MODE)), \ + &proc_##OTYPE##_inode_operations, \ + &proc_##OTYPE##_operations, {}) + /* * Count the number of hardlinks for the pid_entry table, excluding the . * and .. links. @@ -1000,6 +1006,35 @@ out: return err < 0 ? err : count; } +static int oom_adjust_permission(struct inode *inode, int mask) +{ + uid_t uid; + struct task_struct *p; + + p = get_proc_task(inode); + if(p) { + uid = task_uid(p); + put_task_struct(p); + } + + /* + * System Server (uid == 1000) is granted access to oom_adj of all + * android applications (uid > 10000) as and services (uid >= 1000) + */ + if (p && (current_fsuid() == 1000) && (uid >= 1000)) { + if (inode->i_mode >> 6 & mask) { + return 0; + } + } + + /* Fall back to default. */ + return generic_permission(inode, mask); +} + +static const struct inode_operations proc_oom_adj_inode_operations = { + .permission = oom_adjust_permission, +}; + static const struct file_operations proc_oom_adj_operations = { .read = oom_adj_read, .write = oom_adj_write, @@ -2629,7 +2664,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("cgroup", S_IRUGO, proc_cgroup_operations), #endif INF("oom_score", S_IRUGO, proc_oom_score), - REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), + ANDROID("oom_adj", S_IRUGO|S_IWUSR, oom_adj), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), |