* PURPOSE
* Inode handling routines for the OSTA-UDF(tm) filesystem.
*
- * CONTACTS
- * E-mail regarding any portion of the Linux UDF file system should be
- * directed to the development team mailing list (run by majordomo):
- * linux_udf@hpesjro.fc.hp.com
- *
* COPYRIGHT
* This file is distributed under the terms of the GNU General Public
* License (GPL). Copies of the GPL can be obtained from:
kernel_lb_addr, uint32_t, struct buffer_head **);
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
-/*
- * udf_put_inode
- *
- * PURPOSE
- *
- * DESCRIPTION
- * This routine is called whenever the kernel no longer needs the inode.
- *
- * HISTORY
- * July 1, 1997 - Andrew E. Mileski
- * Written, tested, and released.
- *
- * Called at each iput()
- */
-void udf_put_inode(struct inode * inode)
-{
- if (!(inode->i_sb->s_flags & MS_RDONLY))
- {
- lock_kernel();
- udf_discard_prealloc(inode);
- unlock_kernel();
- }
-}
-
/*
* udf_delete_inode
*
*/
void udf_delete_inode(struct inode * inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+
if (is_bad_inode(inode))
goto no_delete;
void udf_clear_inode(struct inode *inode)
{
+ if (!(inode->i_sb->s_flags & MS_RDONLY)) {
+ lock_kernel();
+ udf_discard_prealloc(inode);
+ unlock_kernel();
+ }
+
kfree(UDF_I_DATA(inode));
UDF_I_DATA(inode) = NULL;
}
}
page = grab_cache_page(inode->i_mapping, 0);
- if (!PageLocked(page))
- PAGE_BUG(page);
+ BUG_ON(!PageLocked(page));
+
if (!PageUptodate(page))
{
kaddr = kmap(page);
err = 0;
bh = inode_getblk(inode, block, &err, &phys, &new);
- if (bh)
- BUG();
+ BUG_ON(bh);
if (err)
goto abort;
- if (!phys)
- BUG();
+ BUG_ON(!phys);
if (new)
set_buffer_new(bh_result);
*new = 1;
UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
- inode->i_ctime = CURRENT_TIME;
+ inode->i_ctime = current_fs_time(inode->i_sb);
if (IS_SYNC(inode))
udf_sync_inode(inode);
udf_truncate_extents(inode);
}
- inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
if (IS_SYNC(inode))
udf_sync_inode (inode);
else
unlock_kernel();
}
-/*
- * udf_read_inode
- *
- * PURPOSE
- * Read an inode.
- *
- * DESCRIPTION
- * This routine is called by iget() [which is called by udf_iget()]
- * (clean_inode() will have been called first)
- * when an inode is first read into memory.
- *
- * HISTORY
- * July 1, 1997 - Andrew E. Mileski
- * Written, tested, and released.
- *
- * 12/19/98 dgb Updated to fix size problems.
- */
-
-void
-udf_read_inode(struct inode *inode)
-{
- memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(kernel_lb_addr));
-}
-
static void
__udf_read_inode(struct inode *inode)
{
}
inode->i_uid = le32_to_cpu(fe->uid);
- if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
+ if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb,
+ UDF_FLAG_UID_IGNORE))
+ inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
inode->i_gid = le32_to_cpu(fe->gid);
- if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
+ if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb,
+ UDF_FLAG_GID_IGNORE))
+ inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
if (!inode->i_nlink)
return err;
}
- if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)
- fe->uid = cpu_to_le32(inode->i_uid);
+ if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
+ fe->uid = cpu_to_le32(-1);
+ else fe->uid = cpu_to_le32(inode->i_uid);
- if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)
- fe->gid = cpu_to_le32(inode->i_gid);
+ if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
+ fe->gid = cpu_to_le32(-1);
+ else fe->gid = cpu_to_le32(inode->i_gid);
udfperms = ((inode->i_mode & S_IRWXO) ) |
((inode->i_mode & S_IRWXG) << 2) |
return err;
}
-/*
- * udf_iget
- *
- * PURPOSE
- * Get an inode.
- *
- * DESCRIPTION
- * This routine replaces iget() and read_inode().
- *
- * HISTORY
- * October 3, 1997 - Andrew E. Mileski
- * Written, tested, and released.
- *
- * 12/19/98 dgb Added semaphore and changed to be a wrapper of iget
- */
struct inode *
udf_iget(struct super_block *sb, kernel_lb_addr ino)
{
- struct inode *inode;
- unsigned long block;
-
- block = udf_get_lb_pblock(sb, ino, 0);
-
- /* Get the inode */
-
- inode = iget(sb, block);
- /* calls udf_read_inode() ! */
+ unsigned long block = udf_get_lb_pblock(sb, ino, 0);
+ struct inode *inode = iget_locked(sb, block);
if (!inode)
- {
- printk(KERN_ERR "udf: iget() failed\n");
- return NULL;
- }
- else if (is_bad_inode(inode))
- {
- iput(inode);
return NULL;
- }
- else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF &&
- UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF)
- {
+
+ if (inode->i_state & I_NEW) {
memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
__udf_read_inode(inode);
- if (is_bad_inode(inode))
- {
- iput(inode);
- return NULL;
- }
+ unlock_new_inode(inode);
}
- if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) )
- {
+ if (is_bad_inode(inode))
+ goto out_iput;
+
+ if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
udf_debug("block=%d, partition=%d out of range\n",
ino.logicalBlockNum, ino.partitionReferenceNum);
make_bad_inode(inode);
- iput(inode);
- return NULL;
- }
+ goto out_iput;
+ }
return inode;
+
+ out_iput:
+ iput(inode);
+ return NULL;
}
int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
printk(KERN_ERR "udf: inode_bmap: block < 0\n");
return -1;
}
- if (!inode)
- {
- printk(KERN_ERR "udf: inode_bmap: NULL inode\n");
- return -1;
- }
*extoffset = 0;
*elen = 0;