aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Makefile1
-rw-r--r--fs/aio.c9
-rw-r--r--fs/buffer.c4
-rw-r--r--fs/char_dev.c2
-rw-r--r--fs/ext3/balloc.c135
-rw-r--r--fs/ext3/file.c4
-rw-r--r--fs/ext3/super.c3
-rw-r--r--fs/fat/cache.c2
-rw-r--r--fs/fat/inode.c21
-rw-r--r--fs/freevxfs/vxfs.h1
-rw-r--r--fs/freevxfs/vxfs_bmap.c2
-rw-r--r--fs/freevxfs/vxfs_fshead.c11
-rw-r--r--fs/freevxfs/vxfs_kcompat.h49
-rw-r--r--fs/freevxfs/vxfs_lookup.c8
-rw-r--r--fs/freevxfs/vxfs_olt.c10
-rw-r--r--fs/freevxfs/vxfs_subr.c1
-rw-r--r--fs/freevxfs/vxfs_super.c7
-rw-r--r--fs/ioprio.c172
-rw-r--r--fs/nfs/nfs3acl.c14
-rw-r--r--fs/nfsd/vfs.c13
-rw-r--r--fs/reiserfs/ioctl.c6
-rw-r--r--fs/reiserfs/journal.c12
-rw-r--r--fs/reiserfs/super.c5
-rw-r--r--fs/udf/namei.c6
24 files changed, 325 insertions, 173 deletions
diff --git a/fs/Makefile b/fs/Makefile
index fc92e59e9fa..20edcf28bfd 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,6 +10,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
+ ioprio.o
obj-$(CONFIG_EPOLL) += eventpoll.o
obj-$(CONFIG_COMPAT) += compat.o
diff --git a/fs/aio.c b/fs/aio.c
index 7afa222f680..06d7d4390fe 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -58,6 +58,7 @@ static DEFINE_SPINLOCK(fput_lock);
static LIST_HEAD(fput_head);
static void aio_kick_handler(void *);
+static void aio_queue_work(struct kioctx *);
/* aio_setup
* Creates the slab caches used by the aio routines, panic on
@@ -747,6 +748,14 @@ out:
* has already been kicked */
if (kiocbIsKicked(iocb)) {
__queue_kicked_iocb(iocb);
+
+ /*
+ * __queue_kicked_iocb will always return 1 here, because
+ * iocb->ki_run_list is empty at this point so it should
+ * be safe to unconditionally queue the context into the
+ * work queue.
+ */
+ aio_queue_work(ctx);
}
}
return ret;
diff --git a/fs/buffer.c b/fs/buffer.c
index 13e5938a64f..561e63a1496 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(thaw_bdev);
*/
static void do_sync(unsigned long wait)
{
- wakeup_bdflush(0);
+ wakeup_pdflush(0);
sync_inodes(0); /* All mappings, inodes and their blockdevs */
DQUOT_SYNC(NULL);
sync_supers(); /* Write the superblocks */
@@ -497,7 +497,7 @@ static void free_more_memory(void)
struct zone **zones;
pg_data_t *pgdat;
- wakeup_bdflush(1024);
+ wakeup_pdflush(1024);
yield();
for_each_pgdat(pgdat) {
diff --git a/fs/char_dev.c b/fs/char_dev.c
index e82aac9cc2f..a69a5d8a406 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
struct char_device_struct *cd = NULL, **cp;
int i = major_to_index(major);
- up(&chrdevs_lock);
+ down(&chrdevs_lock);
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
if ((*cp)->major == major &&
(*cp)->baseminor == baseminor &&
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index ccd632fcc6d..e463dca008e 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -749,24 +749,24 @@ fail_access:
* to find a free region that is of my size and has not
* been reserved.
*
- * on succeed, it returns the reservation window to be appended to.
- * failed, return NULL.
*/
-static struct ext3_reserve_window_node *find_next_reservable_window(
+static int find_next_reservable_window(
struct ext3_reserve_window_node *search_head,
- unsigned long size, int *start_block,
+ struct ext3_reserve_window_node *my_rsv,
+ struct super_block * sb, int start_block,
int last_block)
{
struct rb_node *next;
struct ext3_reserve_window_node *rsv, *prev;
int cur;
+ int size = my_rsv->rsv_goal_size;
/* TODO: make the start of the reservation window byte-aligned */
/* cur = *start_block & ~7;*/
- cur = *start_block;
+ cur = start_block;
rsv = search_head;
if (!rsv)
- return NULL;
+ return -1;
while (1) {
if (cur <= rsv->rsv_end)
@@ -782,11 +782,11 @@ static struct ext3_reserve_window_node *find_next_reservable_window(
* space with expected-size (or more)...
*/
if (cur > last_block)
- return NULL; /* fail */
+ return -1; /* fail */
prev = rsv;
next = rb_next(&rsv->rsv_node);
- rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node);
+ rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node);
/*
* Reached the last reservation, we can just append to the
@@ -813,8 +813,25 @@ static struct ext3_reserve_window_node *find_next_reservable_window(
* return the reservation window that we could append to.
* succeed.
*/
- *start_block = cur;
- return prev;
+
+ if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window)))
+ rsv_window_remove(sb, my_rsv);
+
+ /*
+ * Let's book the whole avaliable window for now. We will check the
+ * disk bitmap later and then, if there are free blocks then we adjust
+ * the window size if it's larger than requested.
+ * Otherwise, we will remove this node from the tree next time
+ * call find_next_reservable_window.
+ */
+ my_rsv->rsv_start = cur;
+ my_rsv->rsv_end = cur + size - 1;
+ my_rsv->rsv_alloc_hit = 0;
+
+ if (prev != my_rsv)
+ ext3_rsv_window_add(sb, my_rsv);
+
+ return 0;
}
/**
@@ -852,6 +869,7 @@ static struct ext3_reserve_window_node *find_next_reservable_window(
* @sb: the super block
* @group: the group we are trying to allocate in
* @bitmap_bh: the block group block bitmap
+ *
*/
static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
int goal, struct super_block *sb,
@@ -860,10 +878,10 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
struct ext3_reserve_window_node *search_head;
int group_first_block, group_end_block, start_block;
int first_free_block;
- int reservable_space_start;
- struct ext3_reserve_window_node *prev_rsv;
struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root;
unsigned long size;
+ int ret;
+ spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
group * EXT3_BLOCKS_PER_GROUP(sb);
@@ -875,6 +893,7 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
start_block = goal + group_first_block;
size = my_rsv->rsv_goal_size;
+
if (!rsv_is_empty(&my_rsv->rsv_window)) {
/*
* if the old reservation is cross group boundary
@@ -908,6 +927,8 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
my_rsv->rsv_goal_size= size;
}
}
+
+ spin_lock(rsv_lock);
/*
* shift the search start to the window near the goal block
*/
@@ -921,11 +942,16 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
* need to check the bitmap after we found a reservable window.
*/
retry:
- prev_rsv = find_next_reservable_window(search_head, size,
- &start_block, group_end_block);
- if (prev_rsv == NULL)
- goto failed;
- reservable_space_start = start_block;
+ ret = find_next_reservable_window(search_head, my_rsv, sb,
+ start_block, group_end_block);
+
+ if (ret == -1) {
+ if (!rsv_is_empty(&my_rsv->rsv_window))
+ rsv_window_remove(sb, my_rsv);
+ spin_unlock(rsv_lock);
+ return -1;
+ }
+
/*
* On success, find_next_reservable_window() returns the
* reservation window where there is a reservable space after it.
@@ -937,8 +963,9 @@ retry:
* block. Search start from the start block of the reservable space
* we just found.
*/
+ spin_unlock(rsv_lock);
first_free_block = bitmap_search_next_usable_block(
- reservable_space_start - group_first_block,
+ my_rsv->rsv_start - group_first_block,
bitmap_bh, group_end_block - group_first_block + 1);
if (first_free_block < 0) {
@@ -946,54 +973,29 @@ retry:
* no free block left on the bitmap, no point
* to reserve the space. return failed.
*/
- goto failed;
+ spin_lock(rsv_lock);
+ if (!rsv_is_empty(&my_rsv->rsv_window))
+ rsv_window_remove(sb, my_rsv);
+ spin_unlock(rsv_lock);
+ return -1; /* failed */
}
+
start_block = first_free_block + group_first_block;
/*
* check if the first free block is within the
- * free space we just found
+ * free space we just reserved
*/
- if ((start_block >= reservable_space_start) &&
- (start_block < reservable_space_start + size))
- goto found_rsv_window;
+ if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end)
+ return 0; /* success */
/*
* if the first free bit we found is out of the reservable space
- * this means there is no free block on the reservable space
- * we should continue search for next reservable space,
+ * continue search for next reservable space,
* start from where the free block is,
* we also shift the list head to where we stopped last time
*/
- search_head = prev_rsv;
+ search_head = my_rsv;
+ spin_lock(rsv_lock);
goto retry;
-
-found_rsv_window:
- /*
- * great! the reservable space contains some free blocks.
- * if the search returns that we should add the new
- * window just next to where the old window, we don't
- * need to remove the old window first then add it to the
- * same place, just update the new start and new end.
- */
- if (my_rsv != prev_rsv) {
- if (!rsv_is_empty(&my_rsv->rsv_window))
- rsv_window_remove(sb, my_rsv);
- }
- my_rsv->rsv_start = reservable_space_start;
- my_rsv->rsv_end = my_rsv->rsv_start + size - 1;
- my_rsv->rsv_alloc_hit = 0;
- if (my_rsv != prev_rsv) {
- ext3_rsv_window_add(sb, my_rsv);
- }
- return 0; /* succeed */
-failed:
- /*
- * failed to find a new reservation window in the current
- * group, remove the current(stale) reservation window
- * if there is any
- */
- if (!rsv_is_empty(&my_rsv->rsv_window))
- rsv_window_remove(sb, my_rsv);
- return -1; /* failed */
}
/*
@@ -1023,7 +1025,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
int goal, struct ext3_reserve_window_node * my_rsv,
int *errp)
{
- spinlock_t *rsv_lock;
unsigned long group_first_block;
int ret = 0;
int fatal;
@@ -1052,7 +1053,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
goto out;
}
- rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
/*
* goal is a group relative block number (if there is a goal)
* 0 < goal < EXT3_BLOCKS_PER_GROUP(sb)
@@ -1078,30 +1078,21 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
* then we could go to allocate from the reservation window directly.
*/
while (1) {
- struct ext3_reserve_window rsv_copy;
-
- rsv_copy._rsv_start = my_rsv->rsv_start;
- rsv_copy._rsv_end = my_rsv->rsv_end;
-
- if (rsv_is_empty(&rsv_copy) || (ret < 0) ||
- !goal_in_my_reservation(&rsv_copy, goal, group, sb)) {
- spin_lock(rsv_lock);
+ if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
+ !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) {
ret = alloc_new_reservation(my_rsv, goal, sb,
group, bitmap_bh);
- rsv_copy._rsv_start = my_rsv->rsv_start;
- rsv_copy._rsv_end = my_rsv->rsv_end;
- spin_unlock(rsv_lock);
if (ret < 0)
break; /* failed */
- if (!goal_in_my_reservation(&rsv_copy, goal, group, sb))
+ if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb))
goal = -1;
}
- if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
- || (rsv_copy._rsv_end < group_first_block))
+ if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
+ || (my_rsv->rsv_end < group_first_block))
BUG();
ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
- &rsv_copy);
+ &my_rsv->rsv_window);
if (ret >= 0) {
my_rsv->rsv_alloc_hit++;
break; /* succeed */
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 5ad8cf0292d..98e78345ead 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -36,7 +36,11 @@ static int ext3_release_file (struct inode * inode, struct file * filp)
/* if we are the last writer on the inode, drop the block reservation */
if ((filp->f_mode & FMODE_WRITE) &&
(atomic_read(&inode->i_writecount) == 1))
+ {
+ down(&EXT3_I(inode)->truncate_sem);
ext3_discard_reservation(inode);
+ up(&EXT3_I(inode)->truncate_sem);
+ }
if (is_dx(inode) && filp->private_data)
ext3_htree_free_dir_info(filp->private_data);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index b4b3e8a3913..a6d1779d7de 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -944,7 +944,8 @@ clear_qf_name:
"for remount\n");
return 0;
}
- match_int(&args[0], &option);
+ if (match_int(&args[0], &option) != 0)
+ return 0;
*n_blocks_count = option;
break;
case Opt_nobh:
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 7c52e465a61..77c24fcf712 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -56,7 +56,7 @@ int __init fat_cache_init(void)
return 0;
}
-void __exit fat_cache_destroy(void)
+void fat_cache_destroy(void)
{
if (kmem_cache_destroy(fat_cache_cachep))
printk(KERN_INFO "fat_cache: not all structures were freed\n");
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 8ccee841548..96ae85b67eb 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -1327,16 +1327,25 @@ out_fail:
EXPORT_SYMBOL(fat_fill_super);
int __init fat_cache_init(void);
-void __exit fat_cache_destroy(void);
+void fat_cache_destroy(void);
static int __init init_fat_fs(void)
{
- int ret;
+ int err;
- ret = fat_cache_init();
- if (ret < 0)
- return ret;
- return fat_init_inodecache();
+ err = fat_cache_init();
+ if (err)
+ return err;
+
+ err = fat_init_inodecache();
+ if (err)
+ goto failed;
+
+ return 0;
+
+failed:
+ fat_cache_destroy();
+ return err;
}
static void __exit exit_fat_fs(void)
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
index 8da0252642a..583bd78086d 100644
--- a/fs/freevxfs/vxfs.h
+++ b/fs/freevxfs/vxfs.h
@@ -37,7 +37,6 @@
* superblocks of the Veritas Filesystem.
*/
#include <linux/types.h>
-#include "vxfs_kcompat.h"
/*
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
index bc4b57da306..d3f6b2835bc 100644
--- a/fs/freevxfs/vxfs_bmap.c
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -101,7 +101,7 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
return 0;
fail_size:
- printk("vxfs: indirect extent to big!\n");
+ printk("vxfs: indirect extent too big!\n");
fail_buf:
return 0;
}
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
index 05b19f70bf9..6dee109aeea 100644
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -78,17 +78,18 @@ vxfs_getfsh(struct inode *ip, int which)
struct buffer_head *bp;
bp = vxfs_bread(ip, which);
- if (buffer_mapped(bp)) {
+ if (bp) {
struct vxfs_fsh *fhp;
- if (!(fhp = kmalloc(sizeof(*fhp), SLAB_KERNEL)))
- return NULL;
+ if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
+ goto out;
memcpy(fhp, bp->b_data, sizeof(*fhp));
- brelse(bp);
+ put_bh(bp);
return (fhp);
}
-
+out:
+ brelse(bp);
return NULL;
}
diff --git a/fs/freevxfs/vxfs_kcompat.h b/fs/freevxfs/vxfs_kcompat.h
deleted file mode 100644
index 342a4cc860f..00000000000
--- a/fs/freevxfs/vxfs_kcompat.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _VXFS_KCOMPAT_H
-#define _VXFS_KCOMPAT_H
-
-#include <linux/version.h>
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
-#include <linux/blkdev.h>
-
-typedef long sector_t;
-
-/* From include/linux/fs.h (Linux 2.5.2-pre3) */
-static inline struct buffer_head * sb_bread(struct super_block *sb, int block)
-{
- return bread(sb->s_dev, block, sb->s_blocksize);
-}
-
-/* Dito. */
-static inline void map_bh(struct buffer_head *bh, struct super_block *sb, int block)
-{
- bh->b_state |= 1 << BH_Mapped;
- bh->b_dev = sb->s_dev;
- bh->b_blocknr = block;
-}
-
-/* From fs/block_dev.c (Linux 2.5.2-pre2) */
-static inline int sb_set_blocksize(struct super_block *sb, int size)
-{
- int bits;
- if (set_blocksize(sb->s_dev, size) < 0)
- return 0;
- sb->s_blocksize = size;
- for (bits = 9, size >>= 9; size >>= 1; bits++)
- ;
- sb->s_blocksize_bits = bits;
- return sb->s_blocksize;
-}
-
-/* Dito. */
-static inline int sb_min_blocksize(struct super_block *sb, int size)
-{
- int minsize = get_hardsect_size(sb->s_dev);
- if (size < minsize)
- size = minsize;
- return sb_set_blocksize(sb, size);
-}
-
-#endif /* Kernel 2.4 */
-#endif /* _VXFS_KCOMPAT_H */
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index 506ae251d2c..554eb455722 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -61,13 +61,13 @@ struct file_operations vxfs_dir_operations = {
};
-static __inline__ u_long
+static inline u_long
dir_pages(struct inode *inode)
{
return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
}
-static __inline__ u_long
+static inline u_long
dir_blocks(struct inode *ip)
{
u_long bsize = ip->i_sb->s_blocksize;
@@ -79,7 +79,7 @@ dir_blocks(struct inode *ip)
*
* len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
*/
-static __inline__ int
+static inline int
vxfs_match(int len, const char * const name, struct vxfs_direct *de)
{
if (len != de->d_namelen)
@@ -89,7 +89,7 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de)
return !memcmp(name, de->d_name, len);
}
-static __inline__ struct vxfs_direct *
+static inline struct vxfs_direct *
vxfs_next_entry(struct vxfs_direct *de)
{
return ((struct vxfs_direct *)((char*)de + de->d_reclen));
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 7a204e31aad..133476201d8 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -38,7 +38,7 @@
#include "vxfs_olt.h"
-static __inline__ void
+static inline void
vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
{
if (infp->vsi_fshino)
@@ -46,7 +46,7 @@ vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
infp->vsi_fshino = fshp->olt_fsino[0];
}
-static __inline__ void
+static inline void
vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
{
if (infp->vsi_iext)
@@ -54,7 +54,7 @@ vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
infp->vsi_iext = ilistp->olt_iext[0];
}
-static __inline__ u_long
+static inline u_long
vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
{
if (sbp->s_blocksize % bsize)
@@ -104,8 +104,8 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
goto fail;
}
- oaddr = (char *)bp->b_data + op->olt_size;
- eaddr = (char *)bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
+ oaddr = bp->b_data + op->olt_size;
+ eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
while (oaddr < eaddr) {
struct vxfs_oltcommon *ocp =
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
index 5e305612054..50aae77651b 100644
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -36,7 +36,6 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
-#include "vxfs_kcompat.h"
#include "vxfs_extern.h"
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 0ae2c7b8182..27f66d3e8a0 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -155,12 +155,11 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
sbp->s_flags |= MS_RDONLY;
- infp = kmalloc(sizeof(*infp), GFP_KERNEL);
+ infp = kcalloc(1, sizeof(*infp), GFP_KERNEL);
if (!infp) {
printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
return -ENOMEM;
}
- memset(infp, 0, sizeof(*infp));
bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
if (!bsize) {
@@ -196,7 +195,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
#endif
sbp->s_magic = rsbp->vs_magic;
- sbp->s_fs_info = (void *)infp;
+ sbp->s_fs_info = infp;
infp->vsi_raw = rsbp;
infp->vsi_bp = bp;
@@ -263,7 +262,7 @@ vxfs_init(void)
sizeof(struct vxfs_inode_info), 0,
SLAB_RECLAIM_ACCOUNT, NULL, NULL);
if (vxfs_inode_cachep)
- return (register_filesystem(&vxfs_fs_type));
+ return register_filesystem(&vxfs_fs_type);
return -ENOMEM;
}
diff --git a/fs/ioprio.c b/fs/ioprio.c
new file mode 100644
index 00000000000..663e420636d
--- /dev/null
+++ b/fs/ioprio.c
@@ -0,0 +1,172 @@
+/*
+ * fs/ioprio.c
+ *
+ * Copyright (C) 2004 Jens Axboe <axboe@suse.de>
+ *
+ * Helper functions for setting/querying io priorities of processes. The
+ * system calls closely mimmick getpriority/setpriority, see the man page for
+ * those. The prio argument is a composite of prio class and prio data, where
+ * the data argument has meaning within that class. The standard scheduling
+ * classes have 8 distinct prio levels, with 0 being the highest prio and 7
+ * being the lowest.
+ *
+ * IOW, setting BE scheduling class with prio 2 is done ala:
+ *
+ * unsigned int prio = (IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT) | 2;
+ *
+ * ioprio_set(PRIO_PROCESS, pid, prio);
+ *
+ * See also Documentation/block/ioprio.txt
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/ioprio.h>
+#include <linux/blkdev.h>
+
+static int set_task_ioprio(struct task_struct *task, int ioprio)
+{
+ struct io_context *ioc;
+
+ if (task->uid != current->euid &&
+ task->uid != current->uid && !capable(CAP_SYS_NICE))
+ return -EPERM;
+
+ task_lock(task);
+
+ task->ioprio = ioprio;
+
+ ioc = task->io_context;
+ if (ioc && ioc->set_ioprio)
+ ioc->set_ioprio(ioc, ioprio);
+
+ task_unlock(task);
+ return 0;
+}
+
+asmlinkage int sys_ioprio_set(int which, int who, int ioprio)
+{
+ int class = IOPRIO_PRIO_CLASS(ioprio);
+ int data = IOPRIO_PRIO_DATA(ioprio);
+ struct task_struct *p, *g;
+ struct user_struct *user;
+ int ret;
+
+ switch (class) {
+ case IOPRIO_CLASS_RT:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ /* fall through, rt has prio field too */
+ case IOPRIO_CLASS_BE:
+ if (data >= IOPRIO_BE_NR || data < 0)
+ return -EINVAL;
+
+ break;
+ case IOPRIO_CLASS_IDLE:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = -ESRCH;
+ read_lock_irq(&tasklist_lock);
+ switch (which) {
+ case IOPRIO_WHO_PROCESS:
+ if (!who)
+ p = current;
+ else
+ p = find_task_by_pid(who);
+ if (p)
+ ret = set_task_ioprio(p, ioprio);
+ break;
+ case IOPRIO_WHO_PGRP:
+ if (!who)
+ who = process_group(current);
+ do_each_task_pid(who, PIDTYPE_PGID, p) {
+ ret = set_task_ioprio(p, ioprio);
+ if (ret)
+ break;
+ } while_each_task_pid(who, PIDTYPE_PGID, p);
+ break;
+ case IOPRIO_WHO_USER:
+ if (!who)
+ user = current->user;
+ else
+ user = find_user(who);
+
+ if (!user)
+ break;
+
+ do_each_thread(g, p) {
+ if (p->uid != who)
+ continue;
+ ret = set_task_ioprio(p, ioprio);
+ if (ret)
+ break;
+ } while_each_thread(g, p);
+
+ if (who)
+ free_uid(user);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ read_unlock_irq(&tasklist_lock);
+ return ret;
+}
+
+asmlinkage int sys_ioprio_get(int which, int who)
+{
+ struct task_struct *g, *p;
+ struct user_struct *user;
+ int ret = -ESRCH;
+
+ read_lock_irq(&tasklist_lock);
+ switch (which) {
+ case IOPRIO_WHO_PROCESS:
+ if (!who)
+ p = current;
+ else
+ p = find_task_by_pid(who);
+ if (p)
+ ret = p->ioprio;
+ break;
+ case IOPRIO_WHO_PGRP:
+ if (!who)
+ who = process_group(current);
+ do_each_task_pid(who, PIDTYPE_PGID, p) {
+ if (ret == -ESRCH)
+ ret = p->ioprio;
+ else
+ ret = ioprio_best(ret, p->ioprio);
+ } while_each_task_pid(who, PIDTYPE_PGID, p);
+ break;
+ case IOPRIO_WHO_USER:
+ if (!who)
+ user = current->user;
+ else
+ user = find_user(who);
+
+ if (!user)
+ break;
+
+ do_each_thread(g, p) {
+ if (p->uid != user->uid)
+ continue;
+ if (ret == -ESRCH)
+ ret = p->ioprio;
+ else
+ ret = ioprio_best(ret, p->ioprio);
+ } while_each_thread(g, p);
+
+ if (who)
+ free_uid(user);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ read_unlock_irq(&tasklist_lock);
+ return ret;
+}
+
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index ee3536fc84a..1b7a3ef2f81 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -2,7 +2,7 @@
#include <linux/nfs.h>
#include <linux/nfs3.h>
#include <linux/nfs_fs.h>
-#include <linux/xattr_acl.h>
+#include <linux/posix_acl_xattr.h>
#include <linux/nfsacl.h>
#define NFSDBG_FACILITY NFSDBG_PROC
@@ -53,9 +53,9 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
struct posix_acl *acl;
int type, error = 0;
- if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+ if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
type = ACL_TYPE_ACCESS;
- else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+ else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
type = ACL_TYPE_DEFAULT;
else
return -EOPNOTSUPP;
@@ -82,9 +82,9 @@ int nfs3_setxattr(struct dentry *dentry, const char *name,
struct posix_acl *acl;
int type, error;
- if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+ if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
type = ACL_TYPE_ACCESS;
- else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+ else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
type = ACL_TYPE_DEFAULT;
else
return -EOPNOTSUPP;
@@ -103,9 +103,9 @@ int nfs3_removexattr(struct dentry *dentry, const char *name)
struct inode *inode = dentry->d_inode;
int type;
- if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+ if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
type = ACL_TYPE_ACCESS;
- else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+ else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
type = ACL_TYPE_DEFAULT;
else
return -EOPNOTSUPP;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index de340ffd33c..be24ead89d9 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -46,10 +46,9 @@
#include <linux/nfsd/nfsfh.h>
#include <linux/quotaops.h>
#include <linux/dnotify.h>
-#include <linux/xattr_acl.h>
#include <linux/posix_acl.h>
-#ifdef CONFIG_NFSD_V4
#include <linux/posix_acl_xattr.h>
+#ifdef CONFIG_NFSD_V4
#include <linux/xattr.h>
#include <linux/nfs4.h>
#include <linux/nfs4_acl.h>
@@ -1872,10 +1871,10 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type)
return ERR_PTR(-EOPNOTSUPP);
switch(type) {
case ACL_TYPE_ACCESS:
- name = XATTR_NAME_ACL_ACCESS;
+ name = POSIX_ACL_XATTR_ACCESS;
break;
case ACL_TYPE_DEFAULT:
- name = XATTR_NAME_ACL_DEFAULT;
+ name = POSIX_ACL_XATTR_DEFAULT;
break;
default:
return ERR_PTR(-EOPNOTSUPP);
@@ -1919,17 +1918,17 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
return -EOPNOTSUPP;
switch(type) {
case ACL_TYPE_ACCESS:
- name = XATTR_NAME_ACL_ACCESS;
+ name = POSIX_ACL_XATTR_ACCESS;
break;
case ACL_TYPE_DEFAULT:
- name = XATTR_NAME_ACL_DEFAULT;
+ name = POSIX_ACL_XATTR_DEFAULT;
break;
default:
return -EOPNOTSUPP;
}
if (acl && acl->a_count) {
- size = xattr_acl_size(acl->a_count);
+ size = posix_acl_xattr_size(acl->a_count);
value = kmalloc(size, GFP_KERNEL);
if (!value)
return -ENOMEM;
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 94dc42475a0..76caedf737f 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -36,10 +36,16 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
/* following two cases are taken from fs/ext2/ioctl.c by Remy
Card (card@masi.ibp.fr) */
case REISERFS_IOC_GETFLAGS:
+ if (!reiserfs_attrs (inode->i_sb))
+ return -ENOTTY;
+
flags = REISERFS_I(inode) -> i_attrs;
i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
return put_user(flags, (int __user *) arg);
case REISERFS_IOC_SETFLAGS: {
+ if (!reiserfs_attrs (inode->i_sb))
+ return -ENOTTY;
+
if (IS_RDONLY(inode))
return -EROFS;
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 7b87707acc3..d1bcf0da672 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -645,18 +645,22 @@ struct buffer_chunk {
static void write_chunk(struct buffer_chunk *chunk) {
int i;
+ get_fs_excl();
for (i = 0; i < chunk->nr ; i++) {
submit_logged_buffer(chunk->bh[i]) ;
}
chunk->nr = 0;
+ put_fs_excl();
}
static void write_ordered_chunk(struct buffer_chunk *chunk) {
int i;
+ get_fs_excl();
for (i = 0; i < chunk->nr ; i++) {
submit_ordered_buffer(chunk->bh[i]) ;
}
chunk->nr = 0;
+ put_fs_excl();
}
static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
@@ -918,6 +922,8 @@ static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list
return 0 ;
}
+ get_fs_excl();
+
/* before we can put our commit blocks on disk, we have to make sure everyone older than
** us is on disk too
*/
@@ -1055,6 +1061,7 @@ put_jl:
if (retval)
reiserfs_abort (s, retval, "Journal write error in %s", __FUNCTION__);
+ put_fs_excl();
return retval;
}
@@ -1251,6 +1258,8 @@ static int flush_journal_list(struct super_block *s,
return 0 ;
}
+ get_fs_excl();
+
/* if all the work is already done, get out of here */
if (atomic_read(&(jl->j_nonzerolen)) <= 0 &&
atomic_read(&(jl->j_commit_left)) <= 0) {
@@ -1450,6 +1459,7 @@ flush_older_and_return:
put_journal_list(s, jl);
if (flushall)
up(&journal->j_flush_sem);
+ put_fs_excl();
return err ;
}
@@ -2719,6 +2729,7 @@ relock:
th->t_trans_id = journal->j_trans_id ;
unlock_journal(p_s_sb) ;
INIT_LIST_HEAD (&th->t_list);
+ get_fs_excl();
return 0 ;
out_fail:
@@ -3526,6 +3537,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b
BUG_ON (th->t_refcount > 1);
BUG_ON (!th->t_trans_id);
+ put_fs_excl();
current->journal_info = th->t_handle_save;
reiserfs_check_lock_depth(p_s_sb, "journal end");
if (journal->j_len == 0) {
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 660aefca1fd..4b80ab95d33 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1053,10 +1053,9 @@ static void handle_barrier_mode(struct super_block *s, unsigned long bits) {
static void handle_attrs( struct super_block *s )
{
- struct reiserfs_super_block * rs;
+ struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
if( reiserfs_attrs( s ) ) {
- rs = SB_DISK_SUPER_BLOCK (s);
if( old_format_only(s) ) {
reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" );
REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
@@ -1066,6 +1065,8 @@ static void handle_attrs( struct super_block *s )
reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" );
REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
}
+ } else if (le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared) {
+ REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS;
}
}
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 3f6dc7112bc..ac191ed7df0 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -159,14 +159,12 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
char *nameptr;
uint8_t lfi;
uint16_t liu;
- loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
+ loff_t size;
kernel_lb_addr bloc, eloc;
uint32_t extoffset, elen, offset;
struct buffer_head *bh = NULL;
- if (!dir)
- return NULL;
-
+ size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
f_pos = (udf_ext0_offset(dir) >> 2);
fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;