Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (52 commits)
  split invalidate_inodes()
  fs: skip I_FREEING inodes in writeback_sb_inodes
  fs: fold invalidate_list into invalidate_inodes
  fs: do not drop inode_lock in dispose_list
  fs: inode split IO and LRU lists
  fs: switch bdev inode bdi's correctly
  fs: fix buffer invalidation in invalidate_list
  fsnotify: use dget_parent
  smbfs: use dget_parent
  exportfs: use dget_parent
  fs: use RCU read side protection in d_validate
  fs: clean up dentry lru modification
  fs: split __shrink_dcache_sb
  fs: improve DCACHE_REFERENCED usage
  fs: use percpu counter for nr_dentry and nr_dentry_unused
  fs: simplify __d_free
  fs: take dcache_lock inside __d_path
  fs: do not assign default i_ino in new_inode
  fs: introduce a per-cpu last_ino allocator
  new helper: ihold()
  ...
  • Loading branch information
torvalds committed Oct 27, 2010
2 parents 9e5fca2 + 63997e9 commit 426e1f5
Show file tree
Hide file tree
Showing 118 changed files with 851 additions and 689 deletions.
31 changes: 23 additions & 8 deletions Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -349,21 +349,36 @@ call this method upon the IO completion.

--------------------------- block_device_operations -----------------------
prototypes:
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
int (*open) (struct block_device *, fmode_t);
int (*release) (struct gendisk *, fmode_t);
int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*direct_access) (struct block_device *, sector_t, void **, unsigned long *);
int (*media_changed) (struct gendisk *);
void (*unlock_native_capacity) (struct gendisk *);
int (*revalidate_disk) (struct gendisk *);
int (*getgeo)(struct block_device *, struct hd_geometry *);
void (*swap_slot_free_notify) (struct block_device *, unsigned long);

locking rules:
BKL bd_sem
open: yes yes
release: yes yes
ioctl: yes no
BKL bd_mutex
open: no yes
release: no yes
ioctl: no no
compat_ioctl: no no
direct_access: no no
media_changed: no no
unlock_native_capacity: no no
revalidate_disk: no no
getgeo: no no
swap_slot_free_notify: no no (see below)

media_changed, unlock_native_capacity and revalidate_disk are called only from
check_disk_change().

swap_slot_free_notify is called with swap_lock and sometimes the page lock
held.

The last two are called only from check_disk_change().

--------------------------- file_operations -------------------------------
prototypes:
Expand Down
4 changes: 2 additions & 2 deletions Documentation/filesystems/sharedsubtree.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ replicas continue to be exactly same.
# mount /dev/sd0 /tmp/a

#ls /tmp/a
t1 t2 t2
t1 t2 t3

#ls /mnt/a
t1 t2 t2
t1 t2 t3

Note that the mount has propagated to the mount at /mnt as well.

Expand Down
4 changes: 4 additions & 0 deletions drivers/char/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,10 @@ static int memory_open(struct inode *inode, struct file *filp)
if (dev->dev_info)
filp->f_mapping->backing_dev_info = dev->dev_info;

/* Is /dev/mem or /dev/kmem ? */
if (dev->dev_info == &directly_mappable_cdev_bdi)
filp->f_mode |= FMODE_UNSIGNED_OFFSET;

if (dev->fops->open)
return dev->fops->open(inode, filp);

Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/ipath/ipath_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ static int ipathfs_mknod(struct inode *dir, struct dentry *dentry,
goto bail;
}

inode->i_ino = get_next_ino();
inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_private = data;
Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/hw/qib/qib_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
goto bail;
}

inode->i_ino = get_next_ino();
inode->i_mode = mode;
inode->i_uid = 0;
inode->i_gid = 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/misc/ibmasm/ibmasmfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode)
struct inode *ret = new_inode(sb);

if (ret) {
ret->i_ino = get_next_ino();
ret->i_mode = mode;
ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/oprofile/oprofilefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static struct inode *oprofilefs_get_inode(struct super_block *sb, int mode)
struct inode *inode = new_inode(sb);

if (inode) {
inode->i_ino = get_next_ino();
inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
}
Expand Down
6 changes: 1 addition & 5 deletions drivers/staging/pohmelfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,12 +882,8 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
static int pohmelfs_fsync(struct file *file, int datasync)
{
struct inode *inode = file->f_mapping->host;
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = 0, /* sys_fsync did this */
};

return sync_inode(inode, &wbc);
return sync_inode_metadata(inode, 1);
}

ssize_t pohmelfs_write(struct file *file, const char __user *buf,
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/core/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de
struct inode *inode = new_inode(sb);

if (inode) {
inode->i_ino = get_next_ino();
inode->i_mode = mode;
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ ffs_sb_make_inode(struct super_block *sb, void *data,
if (likely(inode)) {
struct timespec current_time = CURRENT_TIME;

inode->i_ino = usbfs_get_inode();
inode->i_mode = perms->mode;
inode->i_uid = perms->uid;
inode->i_gid = perms->gid;
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1991,6 +1991,7 @@ gadgetfs_make_inode (struct super_block *sb,
struct inode *inode = new_inode (sb);

if (inode) {
inode->i_ino = get_next_ino();
inode->i_mode = mode;
inode->i_uid = default_uid;
inode->i_gid = default_gid;
Expand Down
5 changes: 3 additions & 2 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1789,9 +1789,10 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
kfree(st);
} else {
/* Caching disabled. No need to get upto date stat info.
* This dentry will be released immediately. So, just i_count++
* This dentry will be released immediately. So, just hold the
* inode
*/
atomic_inc(&old_dentry->d_inode->i_count);
ihold(old_dentry->d_inode);
}

dentry->d_op = old_dentry->d_op;
Expand Down
4 changes: 2 additions & 2 deletions fs/affs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,9 +894,9 @@ affs_truncate(struct inode *inode)
if (AFFS_SB(sb)->s_flags & SF_OFS) {
struct buffer_head *bh = affs_bread_ino(inode, last_blk, 0);
u32 tmp;
if (IS_ERR(ext_bh)) {
if (IS_ERR(bh)) {
affs_warning(sb, "truncate", "unexpected read error for last block %u (%d)",
ext, PTR_ERR(ext_bh));
ext, PTR_ERR(bh));
return;
}
tmp = be32_to_cpu(AFFS_DATA_HEAD(bh)->next);
Expand Down
2 changes: 1 addition & 1 deletion fs/affs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
affs_adjust_checksum(inode_bh, block - be32_to_cpu(chain));
mark_buffer_dirty_inode(inode_bh, inode);
inode->i_nlink = 2;
atomic_inc(&inode->i_count);
ihold(inode);
}
affs_fix_checksum(sb, bh);
mark_buffer_dirty_inode(bh, inode);
Expand Down
2 changes: 1 addition & 1 deletion fs/afs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
if (ret < 0)
goto link_error;

atomic_inc(&vnode->vfs_inode.i_count);
ihold(&vnode->vfs_inode);
d_instantiate(dentry, &vnode->vfs_inode);
key_put(key);
_leave(" = 0");
Expand Down
14 changes: 13 additions & 1 deletion fs/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,19 @@ static void aio_batch_add(struct address_space *mapping,
}

abe = mempool_alloc(abe_pool, GFP_KERNEL);
BUG_ON(!igrab(mapping->host));

/*
* we should be using igrab here, but
* we don't want to hammer on the global
* inode spinlock just to take an extra
* reference on a file that we must already
* have a reference to.
*
* When we're called, we always have a reference
* on the file, so we must always have a reference
* on the inode, so ihold() is safe here.
*/
ihold(mapping->host);
abe->mapping = mapping;
hlist_add_head(&abe->list, &batch_hash[bucket]);
return;
Expand Down
6 changes: 3 additions & 3 deletions fs/anon_inodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,9 @@ struct file *anon_inode_getfile(const char *name,
path.mnt = mntget(anon_inode_mnt);
/*
* We know the anon_inode inode count is always greater than zero,
* so we can avoid doing an igrab() and we can use an open-coded
* atomic_inc().
* so ihold() is safe.
*/
atomic_inc(&anon_inode_inode->i_count);
ihold(anon_inode_inode);

path.dentry->d_op = &anon_inodefs_dentry_operations;
d_instantiate(path.dentry, anon_inode_inode);
Expand Down Expand Up @@ -194,6 +193,7 @@ static struct inode *anon_inode_mkinode(void)
if (!inode)
return ERR_PTR(-ENOMEM);

inode->i_ino = get_next_ino();
inode->i_fop = &anon_inode_fops;

inode->i_mapping->a_ops = &anon_aops;
Expand Down
1 change: 1 addition & 0 deletions fs/autofs4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ struct inode *autofs4_get_inode(struct super_block *sb,
inode->i_gid = sb->s_root->d_inode->i_gid;
}
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = get_next_ino();

if (S_ISDIR(inf->mode)) {
inode->i_nlink = 2;
Expand Down
2 changes: 1 addition & 1 deletion fs/bfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ static int bfs_link(struct dentry *old, struct inode *dir,
inc_nlink(inode);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
atomic_inc(&inode->i_count);
ihold(inode);
d_instantiate(new, inode);
mutex_unlock(&info->bfs_lock);
return 0;
Expand Down
1 change: 1 addition & 0 deletions fs/binfmt_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode)
struct inode * inode = new_inode(sb);

if (inode) {
inode->i_ino = get_next_ino();
inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime =
current_fs_time(inode->i_sb);
Expand Down
34 changes: 25 additions & 9 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ inline struct block_device *I_BDEV(struct inode *inode)

EXPORT_SYMBOL(I_BDEV);

/*
* move the inode from it's current bdi to the a new bdi. if the inode is dirty
* we need to move it onto the dirty list of @dst so that the inode is always
* on the right list.
*/
static void bdev_inode_switch_bdi(struct inode *inode,
struct backing_dev_info *dst)
{
spin_lock(&inode_lock);
inode->i_data.backing_dev_info = dst;
if (inode->i_state & I_DIRTY)
list_move(&inode->i_wb_list, &dst->wb.b_dirty);
spin_unlock(&inode_lock);
}

static sector_t max_block(struct block_device *bdev)
{
sector_t retval = ~((sector_t)0);
Expand Down Expand Up @@ -550,7 +565,7 @@ EXPORT_SYMBOL(bdget);
*/
struct block_device *bdgrab(struct block_device *bdev)
{
atomic_inc(&bdev->bd_inode->i_count);
ihold(bdev->bd_inode);
return bdev;
}

Expand Down Expand Up @@ -580,7 +595,7 @@ static struct block_device *bd_acquire(struct inode *inode)
spin_lock(&bdev_lock);
bdev = inode->i_bdev;
if (bdev) {
atomic_inc(&bdev->bd_inode->i_count);
ihold(bdev->bd_inode);
spin_unlock(&bdev_lock);
return bdev;
}
Expand All @@ -591,12 +606,12 @@ static struct block_device *bd_acquire(struct inode *inode)
spin_lock(&bdev_lock);
if (!inode->i_bdev) {
/*
* We take an additional bd_inode->i_count for inode,
* We take an additional reference to bd_inode,
* and it's released in clear_inode() of inode.
* So, we can access it via ->i_mapping always
* without igrab().
*/
atomic_inc(&bdev->bd_inode->i_count);
ihold(bdev->bd_inode);
inode->i_bdev = bdev;
inode->i_mapping = bdev->bd_inode->i_mapping;
list_add(&inode->i_devices, &bdev->bd_inodes);
Expand Down Expand Up @@ -1390,7 +1405,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
bdi = blk_get_backing_dev_info(bdev);
if (bdi == NULL)
bdi = &default_backing_dev_info;
bdev->bd_inode->i_data.backing_dev_info = bdi;
bdev_inode_switch_bdi(bdev->bd_inode, bdi);
}
if (bdev->bd_invalidated)
rescan_partitions(disk, bdev);
Expand All @@ -1405,8 +1420,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
if (ret)
goto out_clear;
bdev->bd_contains = whole;
bdev->bd_inode->i_data.backing_dev_info =
whole->bd_inode->i_data.backing_dev_info;
bdev_inode_switch_bdi(bdev->bd_inode,
whole->bd_inode->i_data.backing_dev_info);
bdev->bd_part = disk_get_part(disk, partno);
if (!(disk->flags & GENHD_FL_UP) ||
!bdev->bd_part || !bdev->bd_part->nr_sects) {
Expand Down Expand Up @@ -1439,7 +1454,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
disk_put_part(bdev->bd_part);
bdev->bd_disk = NULL;
bdev->bd_part = NULL;
bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
bdev_inode_switch_bdi(bdev->bd_inode, &default_backing_dev_info);
if (bdev != bdev->bd_contains)
__blkdev_put(bdev->bd_contains, mode, 1);
bdev->bd_contains = NULL;
Expand Down Expand Up @@ -1533,7 +1548,8 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
disk_put_part(bdev->bd_part);
bdev->bd_part = NULL;
bdev->bd_disk = NULL;
bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
bdev_inode_switch_bdi(bdev->bd_inode,
&default_backing_dev_info);
if (bdev != bdev->bd_contains)
victim = bdev->bd_contains;
bdev->bd_contains = NULL;
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3849,7 +3849,7 @@ static void inode_tree_add(struct inode *inode)
p = &root->inode_tree.rb_node;
parent = NULL;

if (hlist_unhashed(&inode->i_hash))
if (inode_unhashed(inode))
return;

spin_lock(&root->inode_lock);
Expand Down Expand Up @@ -4758,7 +4758,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
}

btrfs_set_trans_block_group(trans, dir);
atomic_inc(&inode->i_count);
ihold(inode);

err = btrfs_add_nondir(trans, dentry, inode, 1, index);

Expand Down
Loading

0 comments on commit 426e1f5

Please sign in to comment.