+/* quota utility function, call if you've had to abort after calling
+** new_inode_init, and have not called reiserfs_new_inode yet.
+** This should only be called on inodes that do not hav stat data
+** inserted into the tree yet.
+*/
+static int drop_new_inode(struct inode *inode) {
+ make_bad_inode(inode) ;
+ iput(inode) ;
+ return 0 ;
+}
+
+/* utility function that does setup for reiserfs_new_inode.
+** DQUOT_ALLOC_INODE cannot be called inside a transaction, so we had
+** to pull some bits of reiserfs_new_inode out into this func.
+*/
+static int new_inode_init(struct inode *inode, struct inode *dir, int mode) {
+
+ /* the quota init calls have to know who to charge the quota to, so
+ ** we have to set uid and gid here
+ */
+ inode->i_uid = current->fsuid;
+ inode->i_mode = mode;
+
+ if (dir->i_mode & S_ISGID) {
+ inode->i_gid = dir->i_gid;
+ if (S_ISDIR(mode))
+ inode->i_mode |= S_ISGID;
+ } else
+ inode->i_gid = current->fsgid;
+ return 0 ;
+}
+
static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
{
int retval;
struct inode * inode;
- int windex ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
struct reiserfs_transaction_handle th ;
inode->i_op = &reiserfs_file_inode_operations;
@@ -520,20 +551,19 @@
if (retval) {
inode->i_nlink--;
reiserfs_update_sd (&th, inode);
- pop_journal_writer(windex) ;
- // FIXME: should we put iput here and have stat data deleted
- // in the same transactioin
journal_end(&th, dir->i_sb, jbegin_count) ;
- iput (inode);
- return retval;
+ iput(inode) ;
+ goto out_failed ;
}
reiserfs_update_inode_transaction(inode) ;
reiserfs_update_inode_transaction(dir) ;
--- linux-2.4.20/fs/reiserfs/inode.c Fri Nov 29 02:53:15 2002
+++ linux-2.4.20-t/fs/reiserfs/inode.c Wed Jan 15 17:08:20 2003
@@ -1463,13 +1463,22 @@
/* inserts the stat data into the tree, and then calls
reiserfs_new_directory (to insert ".", ".." item if new object is
directory) or reiserfs_new_symlink (to insert symlink body if new
- object is symlink) or nothing (if new object is regular file) */
-struct inode * reiserfs_new_inode (struct reiserfs_transaction_handle *th,
- struct inode * dir, int mode,
- const char * symname,
- int i_size, /* 0 for regular, EMTRY_DIR_SIZE for dirs,
- strlen (symname) for symlinks)*/
- struct dentry *dentry, struct inode *inode, int * err)
+ object is symlink) or nothing (if new object is regular file)
+
+ NOTE! uid and gid must already be set in the inode. If we return
+ non-zero due to an error, we have to drop the quota previously allocated
+ for the fresh inode. This can only be done outside a transaction, so
+ if we return non-zero, we also end the transaction.
+
+ */
+int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
+ struct inode * dir, int mode,
+ const char * symname,
+ /* 0 for regular, EMTRY_DIR_SIZE for dirs,
+ strlen (symname) for symlinks) */
+ int i_size,
+ struct dentry *dentry,
+ struct inode *inode)
{
struct super_block * sb;
INITIALIZE_PATH (path_to_key);
@@ -1477,11 +1486,11 @@
struct item_head ih;
struct stat_data sd;
int retval;
+ int err ;
insert_inode_hash (inode);
- // we do not mark inode dirty: on disk content matches to the
- // in-core one
+ reiserfs_update_sd(th, inode) ;
reiserfs_check_path(&path_to_key) ;
- return inode;
+ return 0;
+out_bad_inode:
+ /* Invalidate the object, nothing was inserted yet */
+ INODE_PKEY(inode)->k_objectid = 0;
+
+ /* dquot_drop must be done outside a transaction */
+ journal_end(th, th->t_super, th->t_blocks_allocated) ;
+ make_bad_inode(inode);
+
+out_inserted_sd:
+ inode->i_nlink = 0;
+ th->t_trans_id = 0 ; /* so the caller can't use this handle later */
+ iput(inode) ;
+ return err;
}