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/jack/linux-fs-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6: (33 commits)
  quota: stop using QUOTA_OK / NO_QUOTA
  dquot: cleanup dquot initialize routine
  dquot: move dquot initialization responsibility into the filesystem
  dquot: cleanup dquot drop routine
  dquot: move dquot drop responsibility into the filesystem
  dquot: cleanup dquot transfer routine
  dquot: move dquot transfer responsibility into the filesystem
  dquot: cleanup inode allocation / freeing routines
  dquot: cleanup space allocation / freeing routines
  ext3: add writepage sanity checks
  ext3: Truncate allocated blocks if direct IO write fails to update i_size
  quota: Properly invalidate caches even for filesystems with blocksize < pagesize
  quota: generalize quota transfer interface
  quota: sb_quota state flags cleanup
  jbd: Delay discarding buffers in journal_unmap_buffer
  ext3: quota_write cross block boundary behaviour
  quota: drop permission checks from xfs_fs_set_xstate/xfs_fs_set_xquota
  quota: split out compat_sys_quotactl support from quota.c
  quota: split out netlink notification support from quota.c
  quota: remove invalid optimization from quota_sync_all
  ...

Fixed trivial conflicts in fs/namei.c and fs/ufs/inode.c
  • Loading branch information
torvalds committed Mar 5, 2010
2 parents c812a51 + efd8f0e commit e213e26
Show file tree
Hide file tree
Showing 87 changed files with 1,554 additions and 1,545 deletions.
18 changes: 0 additions & 18 deletions Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,6 @@ in sys_read() and friends.

--------------------------- dquot_operations -------------------------------
prototypes:
int (*initialize) (struct inode *, int);
int (*drop) (struct inode *);
int (*alloc_space) (struct inode *, qsize_t, int);
int (*alloc_inode) (const struct inode *, unsigned long);
int (*free_space) (struct inode *, qsize_t);
int (*free_inode) (const struct inode *, unsigned long);
int (*transfer) (struct inode *, struct iattr *);
int (*write_dquot) (struct dquot *);
int (*acquire_dquot) (struct dquot *);
int (*release_dquot) (struct dquot *);
Expand All @@ -479,13 +472,6 @@ a proper locking wrt the filesystem and call the generic quota operations.
What filesystem should expect from the generic quota functions:

FS recursion Held locks when called
initialize: yes maybe dqonoff_sem
drop: yes -
alloc_space: ->mark_dirty() -
alloc_inode: ->mark_dirty() -
free_space: ->mark_dirty() -
free_inode: ->mark_dirty() -
transfer: yes -
write_dquot: yes dqonoff_sem or dqptr_sem
acquire_dquot: yes dqonoff_sem or dqptr_sem
release_dquot: yes dqonoff_sem or dqptr_sem
Expand All @@ -495,10 +481,6 @@ write_info: yes dqonoff_sem
FS recursion means calling ->quota_read() and ->quota_write() from superblock
operations.

->alloc_space(), ->alloc_inode(), ->free_space(), ->free_inode() are called
only directly by the filesystem and do not call any fs functions only
the ->mark_dirty() operation.

More details about quota locking can be found in fs/dquot.c.

--------------------------- vm_operations_struct -----------------------------
Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/pohmelfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)

if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
(attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
err = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
err = dquot_transfer(inode, attr);
if (err)
goto err_out_exit;
}
Expand Down
11 changes: 2 additions & 9 deletions fs/attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <linux/capability.h>
#include <linux/fsnotify.h>
#include <linux/fcntl.h>
#include <linux/quotaops.h>
#include <linux/security.h>

/* Taken over from the old code... */
Expand Down Expand Up @@ -212,14 +211,8 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
error = inode->i_op->setattr(dentry, attr);
} else {
error = inode_change_ok(inode, attr);
if (!error) {
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
error = vfs_dq_transfer(inode, attr) ?
-EDQUOT : 0;
if (!error)
error = inode_setattr(inode, attr);
}
if (!error)
error = inode_setattr(inode, attr);
}

if (ia_valid & ATTR_SIZE)
Expand Down
12 changes: 7 additions & 5 deletions fs/ext2/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ void ext2_free_blocks (struct inode * inode, unsigned long block,
error_return:
brelse(bitmap_bh);
release_blocks(sb, freed);
vfs_dq_free_block(inode, freed);
dquot_free_block(inode, freed);
}

/**
Expand Down Expand Up @@ -1236,6 +1236,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
unsigned short windowsz = 0;
unsigned long ngroups;
unsigned long num = *count;
int ret;

*errp = -ENOSPC;
sb = inode->i_sb;
Expand All @@ -1247,8 +1248,9 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
/*
* Check quota for allocation of this block.
*/
if (vfs_dq_alloc_block(inode, num)) {
*errp = -EDQUOT;
ret = dquot_alloc_block(inode, num);
if (ret) {
*errp = ret;
return 0;
}

Expand Down Expand Up @@ -1409,7 +1411,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,

*errp = 0;
brelse(bitmap_bh);
vfs_dq_free_block(inode, *count-num);
dquot_free_block(inode, *count-num);
*count = num;
return ret_block;

Expand All @@ -1420,7 +1422,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
* Undo the block allocation
*/
if (!performed_allocation)
vfs_dq_free_block(inode, *count);
dquot_free_block(inode, *count);
brelse(bitmap_bh);
return 0;
}
Expand Down
5 changes: 3 additions & 2 deletions fs/ext2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <linux/time.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include "ext2.h"
#include "xattr.h"
#include "acl.h"
Expand Down Expand Up @@ -70,7 +71,7 @@ const struct file_operations ext2_file_operations = {
.compat_ioctl = ext2_compat_ioctl,
#endif
.mmap = generic_file_mmap,
.open = generic_file_open,
.open = dquot_file_open,
.release = ext2_release_file,
.fsync = ext2_fsync,
.splice_read = generic_file_splice_read,
Expand All @@ -87,7 +88,7 @@ const struct file_operations ext2_xip_file_operations = {
.compat_ioctl = ext2_compat_ioctl,
#endif
.mmap = xip_file_mmap,
.open = generic_file_open,
.open = dquot_file_open,
.release = ext2_release_file,
.fsync = ext2_fsync,
};
Expand Down
14 changes: 7 additions & 7 deletions fs/ext2/ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ void ext2_free_inode (struct inode * inode)
if (!is_bad_inode(inode)) {
/* Quota is already initialized in iput() */
ext2_xattr_delete_inode(inode);
vfs_dq_free_inode(inode);
vfs_dq_drop(inode);
dquot_free_inode(inode);
dquot_drop(inode);
}

es = EXT2_SB(sb)->s_es;
Expand Down Expand Up @@ -586,10 +586,10 @@ struct inode *ext2_new_inode(struct inode *dir, int mode)
goto fail_drop;
}

if (vfs_dq_alloc_inode(inode)) {
err = -EDQUOT;
dquot_initialize(inode);
err = dquot_alloc_inode(inode);
if (err)
goto fail_drop;
}

err = ext2_init_acl(inode, dir);
if (err)
Expand All @@ -605,10 +605,10 @@ struct inode *ext2_new_inode(struct inode *dir, int mode)
return inode;

fail_free_drop:
vfs_dq_free_inode(inode);
dquot_free_inode(inode);

fail_drop:
vfs_dq_drop(inode);
dquot_drop(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
unlock_new_inode(inode);
Expand Down
7 changes: 6 additions & 1 deletion fs/ext2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode)
*/
void ext2_delete_inode (struct inode * inode)
{
if (!is_bad_inode(inode))
dquot_initialize(inode);
truncate_inode_pages(&inode->i_data, 0);

if (is_bad_inode(inode))
Expand Down Expand Up @@ -1464,9 +1466,12 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
error = inode_change_ok(inode, iattr);
if (error)
return error;

if (iattr->ia_valid & ATTR_SIZE)
dquot_initialize(inode);
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0;
error = dquot_transfer(inode, iattr);
if (error)
return error;
}
Expand Down
51 changes: 34 additions & 17 deletions fs/ext2/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*/

#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include "ext2.h"
#include "xattr.h"
#include "acl.h"
Expand Down Expand Up @@ -99,24 +100,27 @@ struct dentry *ext2_get_parent(struct dentry *child)
*/
static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
{
struct inode * inode = ext2_new_inode (dir, mode);
int err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
inode->i_op = &ext2_file_inode_operations;
if (ext2_use_xip(inode->i_sb)) {
inode->i_mapping->a_ops = &ext2_aops_xip;
inode->i_fop = &ext2_xip_file_operations;
} else if (test_opt(inode->i_sb, NOBH)) {
inode->i_mapping->a_ops = &ext2_nobh_aops;
inode->i_fop = &ext2_file_operations;
} else {
inode->i_mapping->a_ops = &ext2_aops;
inode->i_fop = &ext2_file_operations;
}
mark_inode_dirty(inode);
err = ext2_add_nondir(dentry, inode);
struct inode *inode;

dquot_initialize(dir);

inode = ext2_new_inode(dir, mode);
if (IS_ERR(inode))
return PTR_ERR(inode);

inode->i_op = &ext2_file_inode_operations;
if (ext2_use_xip(inode->i_sb)) {
inode->i_mapping->a_ops = &ext2_aops_xip;
inode->i_fop = &ext2_xip_file_operations;
} else if (test_opt(inode->i_sb, NOBH)) {
inode->i_mapping->a_ops = &ext2_nobh_aops;
inode->i_fop = &ext2_file_operations;
} else {
inode->i_mapping->a_ops = &ext2_aops;
inode->i_fop = &ext2_file_operations;
}
return err;
mark_inode_dirty(inode);
return ext2_add_nondir(dentry, inode);
}

static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
Expand All @@ -127,6 +131,8 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_
if (!new_valid_dev(rdev))
return -EINVAL;

dquot_initialize(dir);

inode = ext2_new_inode (dir, mode);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
Expand All @@ -151,6 +157,8 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry,
if (l > sb->s_blocksize)
goto out;

dquot_initialize(dir);

inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
err = PTR_ERR(inode);
if (IS_ERR(inode))
Expand Down Expand Up @@ -194,6 +202,8 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
if (inode->i_nlink >= EXT2_LINK_MAX)
return -EMLINK;

dquot_initialize(dir);

inode->i_ctime = CURRENT_TIME_SEC;
inode_inc_link_count(inode);
atomic_inc(&inode->i_count);
Expand All @@ -216,6 +226,8 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (dir->i_nlink >= EXT2_LINK_MAX)
goto out;

dquot_initialize(dir);

inode_inc_link_count(dir);

inode = ext2_new_inode (dir, S_IFDIR | mode);
Expand Down Expand Up @@ -262,6 +274,8 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry)
struct page * page;
int err = -ENOENT;

dquot_initialize(dir);

de = ext2_find_entry (dir, &dentry->d_name, &page);
if (!de)
goto out;
Expand Down Expand Up @@ -304,6 +318,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
struct ext2_dir_entry_2 * old_de;
int err = -ENOENT;

dquot_initialize(old_dir);
dquot_initialize(new_dir);

old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
if (!old_de)
goto out;
Expand Down
2 changes: 2 additions & 0 deletions fs/ext2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ static void destroy_inodecache(void)
static void ext2_clear_inode(struct inode *inode)
{
struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info;

dquot_drop(inode);
ext2_discard_reservation(inode);
EXT2_I(inode)->i_block_alloc_info = NULL;
if (unlikely(rsv))
Expand Down
10 changes: 5 additions & 5 deletions fs/ext2/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,8 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
the inode. */
ea_bdebug(new_bh, "reusing block");

error = -EDQUOT;
if (vfs_dq_alloc_block(inode, 1)) {
error = dquot_alloc_block(inode, 1);
if (error) {
unlock_buffer(new_bh);
goto cleanup;
}
Expand Down Expand Up @@ -702,7 +702,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
* as if nothing happened and cleanup the unused block */
if (error && error != -ENOSPC) {
if (new_bh && new_bh != old_bh)
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
goto cleanup;
}
} else
Expand Down Expand Up @@ -734,7 +734,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
le32_add_cpu(&HDR(old_bh)->h_refcount, -1);
if (ce)
mb_cache_entry_release(ce);
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
mark_buffer_dirty(old_bh);
ea_bdebug(old_bh, "refcount now=%d",
le32_to_cpu(HDR(old_bh)->h_refcount));
Expand Down Expand Up @@ -797,7 +797,7 @@ ext2_xattr_delete_inode(struct inode *inode)
mark_buffer_dirty(bh);
if (IS_SYNC(inode))
sync_dirty_buffer(bh);
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
}
EXT2_I(inode)->i_file_acl = 0;

Expand Down
Loading

0 comments on commit e213e26

Please sign in to comment.