patch-2.4.17 linux/fs/ext3/inode.c
Next file: linux/fs/ext3/super.c
Previous file: linux/fs/ext3/acl.c
Back to the patch index
Back to the overall index
- Lines: 168
- Date:
Fri Dec 21 16:40:32 2001
- Orig file:
linux-2.4.16/fs/ext3/inode.c
- Orig date:
Fri Nov 9 22:25:04 2001
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.16/fs/ext3/inode.c linux/fs/ext3/inode.c
@@ -32,7 +32,6 @@
#include <linux/quotaops.h>
#include <linux/module.h>
-
/*
* SEARCH_FROM_ZERO forces each block allocation to search from the start
* of the filesystem. This is to force rapid reallocation of recently-freed
@@ -716,6 +715,8 @@
* reachable from inode.
*
* akpm: `handle' can be NULL if create == 0.
+ *
+ * The BKL may not be held on entry here. Be sure to take it early.
*/
static int ext3_get_block_handle(handle_t *handle, struct inode *inode,
@@ -823,6 +824,9 @@
goto reread;
}
+/*
+ * The BKL is not held on entry here.
+ */
static int ext3_get_block(struct inode *inode, long iblock,
struct buffer_head *bh_result, int create)
{
@@ -1022,13 +1026,26 @@
ret = PTR_ERR(handle);
goto out;
}
+ unlock_kernel();
ret = block_prepare_write(page, from, to, ext3_get_block);
+ lock_kernel();
if (ret != 0)
goto prepare_write_failed;
- if (ext3_should_journal_data(inode))
+ if (ext3_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page->buffers,
from, to, NULL, do_journal_get_write_access);
+ if (ret) {
+ /*
+ * We're going to fail this prepare_write(),
+ * so commit_write() will not be called.
+ * We need to undo block_prepare_write()'s kmap().
+ * AKPM: Do we need to clear PageUptodate? I don't
+ * think so.
+ */
+ kunmap(page);
+ }
+ }
prepare_write_failed:
if (ret)
ext3_journal_stop(handle, inode);
@@ -1096,7 +1113,7 @@
kunmap(page);
if (pos > inode->i_size)
inode->i_size = pos;
- set_bit(EXT3_STATE_JDATA, &inode->u.ext3_i.i_state);
+ EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
} else {
if (ext3_should_order_data(inode)) {
ret = walk_page_buffers(handle, page->buffers,
@@ -1104,8 +1121,17 @@
}
/* Be careful here if generic_commit_write becomes a
* required invocation after block_prepare_write. */
- if (ret == 0)
+ if (ret == 0) {
ret = generic_commit_write(file, page, from, to);
+ } else {
+ /*
+ * block_prepare_write() was called, but we're not
+ * going to call generic_commit_write(). So we
+ * need to perform generic_commit_write()'s kunmap
+ * by hand.
+ */
+ kunmap(page);
+ }
}
if (inode->i_size > inode->u.ext3_i.i_disksize) {
inode->u.ext3_i.i_disksize = inode->i_size;
@@ -1140,7 +1166,7 @@
journal_t *journal;
int err;
- if (test_and_clear_bit(EXT3_STATE_JDATA, &inode->u.ext3_i.i_state)) {
+ if (EXT3_I(inode)->i_state & EXT3_STATE_JDATA) {
/*
* This is a REALLY heavyweight approach, but the use of
* bmap on dirty files is expected to be extremely rare:
@@ -1159,6 +1185,7 @@
* everything they get.
*/
+ EXT3_I(inode)->i_state &= ~EXT3_STATE_JDATA;
journal = EXT3_JOURNAL(inode);
journal_lock_updates(journal);
err = journal_flush(journal);
@@ -2203,7 +2230,7 @@
/* If we are not tracking these fields in the in-memory inode,
* then preserve them on disk, but still initialise them to zero
* for new inodes. */
- if (inode->u.ext3_i.i_state & EXT3_STATE_NEW) {
+ if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) {
raw_inode->i_faddr = 0;
raw_inode->i_frag = 0;
raw_inode->i_fsize = 0;
@@ -2249,7 +2276,7 @@
rc = ext3_journal_dirty_metadata(handle, bh);
if (!err)
err = rc;
- inode->u.ext3_i.i_state &= ~EXT3_STATE_NEW;
+ EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW;
out_brelse:
brelse (bh);
@@ -2333,12 +2360,20 @@
int ext3_setattr(struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = dentry->d_inode;
- int error, rc;
+ int error, rc = 0;
+ const unsigned int ia_valid = attr->ia_valid;
error = inode_change_ok(inode, attr);
if (error)
return error;
-
+
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+ error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+ if (error)
+ return error;
+ }
+
if (attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
handle_t *handle;
@@ -2356,7 +2391,7 @@
ext3_journal_stop(handle, inode);
}
- inode_setattr(inode, attr);
+ rc = inode_setattr(inode, attr);
/* If inode_setattr's call to ext3_truncate failed to get a
* transaction handle at all, we need to clean up the in-core
@@ -2366,7 +2401,9 @@
err_out:
ext3_std_error(inode->i_sb, error);
- return 0;
+ if (!error)
+ error = rc;
+ return error;
}
@@ -2667,6 +2704,3 @@
* here, in ext3_aops_journal_start() to ensure that the forthcoming "see if we
* need to extend" test in ext3_prepare_write() succeeds.
*/
-
-
-MODULE_LICENSE("GPL");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)