Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb78be83 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
  [PATCH] fix SMP ordering hole in fcntl_setlk()
  [PATCH] kill ->put_inode
  [PATCH] fix reservation discarding in affs
parents 31d9168d 0b2bac2f
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -92,7 +92,6 @@ prototypes:
	void (*destroy_inode)(struct inode *);
	void (*destroy_inode)(struct inode *);
	void (*dirty_inode) (struct inode *);
	void (*dirty_inode) (struct inode *);
	int (*write_inode) (struct inode *, int);
	int (*write_inode) (struct inode *, int);
	void (*put_inode) (struct inode *);
	void (*drop_inode) (struct inode *);
	void (*drop_inode) (struct inode *);
	void (*delete_inode) (struct inode *);
	void (*delete_inode) (struct inode *);
	void (*put_super) (struct super_block *);
	void (*put_super) (struct super_block *);
@@ -115,7 +114,6 @@ alloc_inode: no no no
destroy_inode:		no
destroy_inode:		no
dirty_inode:		no				(must not sleep)
dirty_inode:		no				(must not sleep)
write_inode:		no
write_inode:		no
put_inode:		no
drop_inode:		no				!!!inode_lock!!!
drop_inode:		no				!!!inode_lock!!!
delete_inode:		no
delete_inode:		no
put_super:		yes	yes	no
put_super:		yes	yes	no
+0 −4
Original line number Original line Diff line number Diff line
@@ -205,7 +205,6 @@ struct super_operations {


        void (*dirty_inode) (struct inode *);
        void (*dirty_inode) (struct inode *);
        int (*write_inode) (struct inode *, int);
        int (*write_inode) (struct inode *, int);
        void (*put_inode) (struct inode *);
        void (*drop_inode) (struct inode *);
        void (*drop_inode) (struct inode *);
        void (*delete_inode) (struct inode *);
        void (*delete_inode) (struct inode *);
        void (*put_super) (struct super_block *);
        void (*put_super) (struct super_block *);
@@ -246,9 +245,6 @@ or bottom half).
	inode to disc.  The second parameter indicates whether the write
	inode to disc.  The second parameter indicates whether the write
	should be synchronous or not, not all filesystems check this flag.
	should be synchronous or not, not all filesystems check this flag.


  put_inode: called when the VFS inode is removed from the inode
	cache.

  drop_inode: called when the last access to the inode is dropped,
  drop_inode: called when the last access to the inode is dropped,
	with the inode_lock spinlock held.
	with the inode_lock spinlock held.


+1 −3
Original line number Original line Diff line number Diff line
@@ -48,7 +48,7 @@ struct affs_ext_key {
 * affs fs inode data in memory
 * affs fs inode data in memory
 */
 */
struct affs_inode_info {
struct affs_inode_info {
	u32	 i_opencnt;
	atomic_t i_opencnt;
	struct semaphore i_link_lock;		/* Protects internal inode access. */
	struct semaphore i_link_lock;		/* Protects internal inode access. */
	struct semaphore i_ext_lock;		/* Protects internal inode access. */
	struct semaphore i_ext_lock;		/* Protects internal inode access. */
#define i_hash_lock i_ext_lock
#define i_hash_lock i_ext_lock
@@ -170,8 +170,6 @@ extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry,
extern unsigned long		 affs_parent_ino(struct inode *dir);
extern unsigned long		 affs_parent_ino(struct inode *dir);
extern struct inode		*affs_new_inode(struct inode *dir);
extern struct inode		*affs_new_inode(struct inode *dir);
extern int			 affs_notify_change(struct dentry *dentry, struct iattr *attr);
extern int			 affs_notify_change(struct dentry *dentry, struct iattr *attr);
extern void			 affs_put_inode(struct inode *inode);
extern void			 affs_drop_inode(struct inode *inode);
extern void			 affs_delete_inode(struct inode *inode);
extern void			 affs_delete_inode(struct inode *inode);
extern void			 affs_clear_inode(struct inode *inode);
extern void			 affs_clear_inode(struct inode *inode);
extern struct inode		*affs_iget(struct super_block *sb,
extern struct inode		*affs_iget(struct super_block *sb,
+17 −8
Original line number Original line Diff line number Diff line
@@ -48,8 +48,9 @@ affs_file_open(struct inode *inode, struct file *filp)
{
{
	if (atomic_read(&filp->f_count) != 1)
	if (atomic_read(&filp->f_count) != 1)
		return 0;
		return 0;
	pr_debug("AFFS: open(%d)\n", AFFS_I(inode)->i_opencnt);
	pr_debug("AFFS: open(%lu,%d)\n",
	AFFS_I(inode)->i_opencnt++;
		 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
	atomic_inc(&AFFS_I(inode)->i_opencnt);
	return 0;
	return 0;
}
}


@@ -58,10 +59,16 @@ affs_file_release(struct inode *inode, struct file *filp)
{
{
	if (atomic_read(&filp->f_count) != 0)
	if (atomic_read(&filp->f_count) != 0)
		return 0;
		return 0;
	pr_debug("AFFS: release(%d)\n", AFFS_I(inode)->i_opencnt);
	pr_debug("AFFS: release(%lu, %d)\n",
	AFFS_I(inode)->i_opencnt--;
		 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
	if (!AFFS_I(inode)->i_opencnt)

	if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) {
		mutex_lock(&inode->i_mutex);
		if (inode->i_size != AFFS_I(inode)->mmu_private)
			affs_truncate(inode);
		affs_free_prealloc(inode);
		affs_free_prealloc(inode);
		mutex_unlock(&inode->i_mutex);
	}


	return 0;
	return 0;
}
}
@@ -180,7 +187,7 @@ affs_get_extblock(struct inode *inode, u32 ext)
	/* inline the simplest case: same extended block as last time */
	/* inline the simplest case: same extended block as last time */
	struct buffer_head *bh = AFFS_I(inode)->i_ext_bh;
	struct buffer_head *bh = AFFS_I(inode)->i_ext_bh;
	if (ext == AFFS_I(inode)->i_ext_last)
	if (ext == AFFS_I(inode)->i_ext_last)
		atomic_inc(&bh->b_count);
		get_bh(bh);
	else
	else
		/* we have to do more (not inlined) */
		/* we have to do more (not inlined) */
		bh = affs_get_extblock_slow(inode, ext);
		bh = affs_get_extblock_slow(inode, ext);
@@ -306,7 +313,7 @@ affs_get_extblock_slow(struct inode *inode, u32 ext)
	affs_brelse(AFFS_I(inode)->i_ext_bh);
	affs_brelse(AFFS_I(inode)->i_ext_bh);
	AFFS_I(inode)->i_ext_last = ext;
	AFFS_I(inode)->i_ext_last = ext;
	AFFS_I(inode)->i_ext_bh = bh;
	AFFS_I(inode)->i_ext_bh = bh;
	atomic_inc(&bh->b_count);
	get_bh(bh);


	return bh;
	return bh;


@@ -324,7 +331,6 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul


	pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block);
	pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block);



	BUG_ON(block > (sector_t)0x7fffffffUL);
	BUG_ON(block > (sector_t)0x7fffffffUL);


	if (block >= AFFS_I(inode)->i_blkcnt) {
	if (block >= AFFS_I(inode)->i_blkcnt) {
@@ -827,6 +833,8 @@ affs_truncate(struct inode *inode)
		res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
		res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
		if (!res)
		if (!res)
			res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
			res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
		else
			inode->i_size = AFFS_I(inode)->mmu_private;
		mark_inode_dirty(inode);
		mark_inode_dirty(inode);
		return;
		return;
	} else if (inode->i_size == AFFS_I(inode)->mmu_private)
	} else if (inode->i_size == AFFS_I(inode)->mmu_private)
@@ -862,6 +870,7 @@ affs_truncate(struct inode *inode)
		blk++;
		blk++;
	} else
	} else
		AFFS_HEAD(ext_bh)->first_data = 0;
		AFFS_HEAD(ext_bh)->first_data = 0;
	AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i);
	size = AFFS_SB(sb)->s_hashsize;
	size = AFFS_SB(sb)->s_hashsize;
	if (size > blkcnt - blk + i)
	if (size > blkcnt - blk + i)
		size = blkcnt - blk + i;
		size = blkcnt - blk + i;
+8 −26
Original line number Original line Diff line number Diff line
@@ -58,7 +58,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
	AFFS_I(inode)->i_extcnt = 1;
	AFFS_I(inode)->i_extcnt = 1;
	AFFS_I(inode)->i_ext_last = ~1;
	AFFS_I(inode)->i_ext_last = ~1;
	AFFS_I(inode)->i_protect = prot;
	AFFS_I(inode)->i_protect = prot;
	AFFS_I(inode)->i_opencnt = 0;
	atomic_set(&AFFS_I(inode)->i_opencnt, 0);
	AFFS_I(inode)->i_blkcnt = 0;
	AFFS_I(inode)->i_blkcnt = 0;
	AFFS_I(inode)->i_lc = NULL;
	AFFS_I(inode)->i_lc = NULL;
	AFFS_I(inode)->i_lc_size = 0;
	AFFS_I(inode)->i_lc_size = 0;
@@ -108,8 +108,6 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
			inode->i_mode |= S_IFDIR;
			inode->i_mode |= S_IFDIR;
		} else
		} else
			inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
			inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
		if (tail->link_chain)
			inode->i_nlink = 2;
		/* Maybe it should be controlled by mount parameter? */
		/* Maybe it should be controlled by mount parameter? */
		//inode->i_mode |= S_ISVTX;
		//inode->i_mode |= S_ISVTX;
		inode->i_op = &affs_dir_inode_operations;
		inode->i_op = &affs_dir_inode_operations;
@@ -244,31 +242,12 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
	return error;
	return error;
}
}


void
affs_put_inode(struct inode *inode)
{
	pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
	affs_free_prealloc(inode);
}

void
affs_drop_inode(struct inode *inode)
{
	mutex_lock(&inode->i_mutex);
	if (inode->i_size != AFFS_I(inode)->mmu_private)
		affs_truncate(inode);
	mutex_unlock(&inode->i_mutex);

	generic_drop_inode(inode);
}

void
void
affs_delete_inode(struct inode *inode)
affs_delete_inode(struct inode *inode)
{
{
	pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
	pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
	truncate_inode_pages(&inode->i_data, 0);
	truncate_inode_pages(&inode->i_data, 0);
	inode->i_size = 0;
	inode->i_size = 0;
	if (S_ISREG(inode->i_mode))
	affs_truncate(inode);
	affs_truncate(inode);
	clear_inode(inode);
	clear_inode(inode);
	affs_free_block(inode->i_sb, inode->i_ino);
	affs_free_block(inode->i_sb, inode->i_ino);
@@ -277,9 +256,12 @@ affs_delete_inode(struct inode *inode)
void
void
affs_clear_inode(struct inode *inode)
affs_clear_inode(struct inode *inode)
{
{
	unsigned long cache_page = (unsigned long) AFFS_I(inode)->i_lc;
	unsigned long cache_page;


	pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
	pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);

	affs_free_prealloc(inode);
	cache_page = (unsigned long)AFFS_I(inode)->i_lc;
	if (cache_page) {
	if (cache_page) {
		pr_debug("AFFS: freeing ext cache\n");
		pr_debug("AFFS: freeing ext cache\n");
		AFFS_I(inode)->i_lc = NULL;
		AFFS_I(inode)->i_lc = NULL;
@@ -316,7 +298,7 @@ affs_new_inode(struct inode *dir)
	inode->i_ino     = block;
	inode->i_ino     = block;
	inode->i_nlink   = 1;
	inode->i_nlink   = 1;
	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
	AFFS_I(inode)->i_opencnt = 0;
	atomic_set(&AFFS_I(inode)->i_opencnt, 0);
	AFFS_I(inode)->i_blkcnt = 0;
	AFFS_I(inode)->i_blkcnt = 0;
	AFFS_I(inode)->i_lc = NULL;
	AFFS_I(inode)->i_lc = NULL;
	AFFS_I(inode)->i_lc_size = 0;
	AFFS_I(inode)->i_lc_size = 0;
@@ -369,12 +351,12 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
	switch (type) {
	switch (type) {
	case ST_LINKFILE:
	case ST_LINKFILE:
	case ST_LINKDIR:
	case ST_LINKDIR:
		inode_bh = bh;
		retval = -ENOSPC;
		retval = -ENOSPC;
		block = affs_alloc_block(dir, dir->i_ino);
		block = affs_alloc_block(dir, dir->i_ino);
		if (!block)
		if (!block)
			goto err;
			goto err;
		retval = -EIO;
		retval = -EIO;
		inode_bh = bh;
		bh = affs_getzeroblk(sb, block);
		bh = affs_getzeroblk(sb, block);
		if (!bh)
		if (!bh)
			goto err;
			goto err;
Loading