static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode, struct nameidata *nd) { int retval; struct inode * inode; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ; struct reiserfs_transaction_handle th ; int locked; if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM ; } retval = new_inode_init(inode, dir, mode); if (retval) return retval; locked = reiserfs_cache_default_acl (dir); reiserfs_write_lock(dir->i_sb); if (locked) reiserfs_write_lock_xattrs (dir->i_sb); journal_begin(&th, dir->i_sb, jbegin_count) ; retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode); if (locked) reiserfs_write_unlock_xattrs (dir->i_sb); if (retval) { goto out_failed; } inode->i_op = &reiserfs_file_inode_operations; inode->i_fop = &reiserfs_file_operations; inode->i_mapping->a_ops = &reiserfs_address_space_operations ; retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, inode, 1/*visible*/); if (retval) { inode->i_nlink--; reiserfs_update_sd (&th, inode); journal_end(&th, dir->i_sb, jbegin_count) ; iput (inode); goto out_failed; } reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(dir) ; d_instantiate(dentry, inode); journal_end(&th, dir->i_sb, jbegin_count) ; out_failed: reiserfs_write_unlock(dir->i_sb); return retval; }
int reiserfs_acl_chmod (struct inode *inode) { struct posix_acl *acl, *clone; int error; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (get_inode_sd_version (inode) == STAT_DATA_V1 || !reiserfs_posixacl(inode->i_sb)) { return 0; } reiserfs_read_lock_xattrs (inode->i_sb); acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); reiserfs_read_unlock_xattrs (inode->i_sb); if (!acl) return 0; if (IS_ERR(acl)) return PTR_ERR(acl); clone = posix_acl_clone(acl, GFP_NOFS); posix_acl_release(acl); if (!clone) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); if (!error) { int lock = !has_xattr_dir (inode); reiserfs_write_lock_xattr_i (inode); if (lock) reiserfs_write_lock_xattrs (inode->i_sb); else reiserfs_read_lock_xattrs (inode->i_sb); error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone); if (lock) reiserfs_write_unlock_xattrs (inode->i_sb); else reiserfs_read_unlock_xattrs (inode->i_sb); reiserfs_write_unlock_xattr_i (inode); } posix_acl_release(clone); return error; }
static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode) { int retval; struct inode * inode; struct reiserfs_transaction_handle th ; /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); int locked; #ifdef DISPLACE_NEW_PACKING_LOCALITIES /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ REISERFS_I(dir)->new_packing_locality = 1; #endif mode = S_IFDIR | mode; if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM ; } new_inode_init(inode, dir, mode); locked = reiserfs_cache_default_acl (dir); reiserfs_write_lock(dir->i_sb); if (locked) reiserfs_write_lock_xattrs (dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count) ; if (retval) { drop_new_inode (inode); goto out_failed; } /* inc the link count now, so another writer doesn't overflow it while ** we sleep later on. */ INC_DIR_INODE_NLINK(dir) retval = reiserfs_new_inode (&th, dir, mode, NULL/*symlink*/, old_format_only (dir->i_sb) ? EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE, dentry, inode); if (retval) { dir->i_nlink-- ; goto out_failed; } if (locked) { reiserfs_write_unlock_xattrs (dir->i_sb); locked = 0; } reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(dir) ; inode->i_op = &reiserfs_dir_inode_operations; inode->i_fop = &reiserfs_dir_operations; // note, _this_ add_entry will not update dir's stat data retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, inode, 1/*visible*/); if (retval) { int err; inode->i_nlink = 0; DEC_DIR_INODE_NLINK(dir); reiserfs_update_sd (&th, inode); err = journal_end(&th, dir->i_sb, jbegin_count) ; if (err) retval = err; iput (inode); goto out_failed; } // the above add_entry did not update dir's stat data reiserfs_update_sd (&th, dir); d_instantiate(dentry, inode); retval = journal_end(&th, dir->i_sb, jbegin_count) ; out_failed: if (locked) reiserfs_write_unlock_xattrs (dir->i_sb); reiserfs_write_unlock(dir->i_sb); return retval; }
static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { int retval; struct inode * inode; struct reiserfs_transaction_handle th ; /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); int locked; if (!new_valid_dev(rdev)) return -EINVAL; if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM ; } new_inode_init(inode, dir, mode); locked = reiserfs_cache_default_acl (dir); reiserfs_write_lock(dir->i_sb); if (locked) reiserfs_write_lock_xattrs (dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count) ; if (retval) { drop_new_inode (inode); goto out_failed; } retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode); if (retval) { goto out_failed; } if (locked) { reiserfs_write_unlock_xattrs (dir->i_sb); locked = 0; } inode->i_op = &reiserfs_special_inode_operations; init_special_inode(inode, inode->i_mode, rdev) ; //FIXME: needed for block and char devices only reiserfs_update_sd (&th, inode); reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(dir) ; retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, inode, 1/*visible*/); if (retval) { int err; inode->i_nlink--; reiserfs_update_sd (&th, inode); err = journal_end(&th, dir->i_sb, jbegin_count) ; if (err) retval = err; iput (inode); goto out_failed; } d_instantiate(dentry, inode); retval = journal_end(&th, dir->i_sb, jbegin_count) ; out_failed: if (locked) reiserfs_write_unlock_xattrs (dir->i_sb); reiserfs_write_unlock(dir->i_sb); return retval; }
static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode, struct nameidata *nd) { int retval; struct inode * inode; /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); struct reiserfs_transaction_handle th ; int locked; if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM ; } new_inode_init(inode, dir, mode); locked = reiserfs_cache_default_acl (dir); reiserfs_write_lock(dir->i_sb); if (locked) reiserfs_write_lock_xattrs (dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count); if (retval) { drop_new_inode (inode); goto out_failed; } retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode); if (retval) goto out_failed; if (locked) { reiserfs_write_unlock_xattrs (dir->i_sb); locked = 0; } inode->i_op = &reiserfs_file_inode_operations; inode->i_fop = &reiserfs_file_operations; inode->i_mapping->a_ops = &reiserfs_address_space_operations ; retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, inode, 1/*visible*/); if (retval) { int err; inode->i_nlink--; reiserfs_update_sd (&th, inode); err = journal_end(&th, dir->i_sb, jbegin_count) ; if (err) retval = err; iput (inode); goto out_failed; } reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(dir) ; d_instantiate(dentry, inode); retval = journal_end(&th, dir->i_sb, jbegin_count) ; out_failed: if (locked) reiserfs_write_unlock_xattrs (dir->i_sb); reiserfs_write_unlock(dir->i_sb); return retval; }
static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { int retval; struct inode * inode; struct reiserfs_transaction_handle th ; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; int locked; if (!new_valid_dev(rdev)) return -EINVAL; if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM ; } retval = new_inode_init(inode, dir, mode); if (retval) return retval; locked = reiserfs_cache_default_acl (dir); reiserfs_write_lock(dir->i_sb); if (locked) reiserfs_write_lock_xattrs (dir->i_sb); journal_begin(&th, dir->i_sb, jbegin_count) ; retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode); if (locked) reiserfs_write_unlock_xattrs (dir->i_sb); if (retval) { goto out_failed; } inode->i_op = &reiserfs_special_inode_operations; init_special_inode(inode, inode->i_mode, rdev) ; //FIXME: needed for block and char devices only reiserfs_update_sd (&th, inode); reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(dir) ; retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, inode, 1/*visible*/); if (retval) { inode->i_nlink--; reiserfs_update_sd (&th, inode); journal_end(&th, dir->i_sb, jbegin_count) ; iput (inode); goto out_failed; } d_instantiate(dentry, inode); journal_end(&th, dir->i_sb, jbegin_count) ; out_failed: reiserfs_write_unlock(dir->i_sb); return retval; }