File: /usr/src/linux/fs/udf/ialloc.c

1     /*
2      * ialloc.c
3      *
4      * PURPOSE
5      *	Inode allocation handling routines for the OSTA-UDF(tm) filesystem.
6      *
7      * CONTACTS
8      *	E-mail regarding any portion of the Linux UDF file system should be
9      *	directed to the development team mailing list (run by majordomo):
10      *		linux_udf@hpesjro.fc.hp.com
11      *
12      * COPYRIGHT
13      *	This file is distributed under the terms of the GNU General Public
14      *	License (GPL). Copies of the GPL can be obtained from:
15      *		ftp://prep.ai.mit.edu/pub/gnu/GPL
16      *	Each contributing author retains all rights to their own work.
17      *
18      *  (C) 1998-2000 Ben Fennema
19      *
20      * HISTORY
21      *
22      *  02/24/99 blf  Created.
23      *
24      */
25     
26     #include "udfdecl.h"
27     #include <linux/fs.h>
28     #include <linux/locks.h>
29     #include <linux/quotaops.h>
30     #include <linux/udf_fs.h>
31     
32     #include "udf_i.h"
33     #include "udf_sb.h"
34     
35     void udf_free_inode(struct inode * inode)
36     {
37     	struct super_block * sb = inode->i_sb;
38     	int is_directory;
39     	unsigned long ino;
40     
41     	ino = inode->i_ino;
42     
43     	/*
44     	 * Note: we must free any quota before locking the superblock,
45     	 * as writing the quota to disk may need the lock as well.
46     	 */
47     	DQUOT_FREE_INODE(sb, inode);
48     	DQUOT_DROP(inode);
49     
50     	lock_super(sb);
51     
52     	is_directory = S_ISDIR(inode->i_mode);
53     
54     	clear_inode(inode);
55     
56     	if (UDF_SB_LVIDBH(sb))
57     	{
58     		if (is_directory)
59     			UDF_SB_LVIDIU(sb)->numDirs =
60     				cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1);
61     		else
62     			UDF_SB_LVIDIU(sb)->numFiles =
63     				cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1);
64     		
65     		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
66     	}
67     
68     	unlock_super(sb);
69     
70     	udf_free_blocks(inode, UDF_I_LOCATION(inode), 0, 1);
71     }
72     
73     struct inode * udf_new_inode (const struct inode *dir, int mode, int * err)
74     {
75     	struct super_block *sb;
76     	struct inode * inode;
77     	int block;
78     	Uint32 start = UDF_I_LOCATION(dir).logicalBlockNum;
79     
80     	sb = dir->i_sb;
81     	inode = new_inode(sb);
82     
83     	if (!inode)
84     	{
85     		*err = -ENOMEM;
86     		return NULL;
87     	}
88     	*err = -ENOSPC;
89     
90     	block = udf_new_block(dir, UDF_I_LOCATION(dir).partitionReferenceNum,
91     		start, err);
92     	if (*err)
93     	{
94     		iput(inode);
95     		return NULL;
96     	}
97     	lock_super(sb);
98     
99     	if (UDF_SB_LVIDBH(sb))
100     	{
101     		struct LogicalVolHeaderDesc *lvhd;
102     		Uint64 uniqueID;
103     		lvhd = (struct LogicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
104     		if (S_ISDIR(mode))
105     			UDF_SB_LVIDIU(sb)->numDirs =
106     				cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1);
107     		else
108     			UDF_SB_LVIDIU(sb)->numFiles =
109     				cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1);
110     		UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID);
111     		if (!(++uniqueID & 0x00000000FFFFFFFFUL))
112     			uniqueID += 16;
113     		lvhd->uniqueID = cpu_to_le64(uniqueID);
114     		mark_buffer_dirty(UDF_SB_LVIDBH(sb));
115     	}
116     	inode->i_mode = mode;
117     	inode->i_uid = current->fsuid;
118     	if (dir->i_mode & S_ISGID)
119     	{
120     		inode->i_gid = dir->i_gid;
121     		if (S_ISDIR(mode))
122     			mode |= S_ISGID;
123     	}
124     	else
125     		inode->i_gid = current->fsgid;
126     
127     	UDF_I_LOCATION(inode).logicalBlockNum = block;
128     	UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
129     	inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
130     	inode->i_blksize = PAGE_SIZE;
131     	inode->i_blocks = 0;
132     	UDF_I_LENEATTR(inode) = 0;
133     	UDF_I_LENALLOC(inode) = 0;
134     	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE))
135     	{
136     		UDF_I_EXTENDED_FE(inode) = 1;
137     		UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
138     	}
139     	else
140     		UDF_I_EXTENDED_FE(inode) = 0;
141     	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
142     		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_IN_ICB;
143     	else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
144     		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_SHORT;
145     	else
146     		UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
147     	inode->i_mtime = inode->i_atime = inode->i_ctime =
148     		UDF_I_CRTIME(inode) = CURRENT_TIME;
149     	UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) =
150     		UDF_I_UCRTIME(inode) = CURRENT_UTIME;
151     	UDF_I_NEW_INODE(inode) = 1;
152     	insert_inode_hash(inode);
153     	mark_inode_dirty(inode);
154     
155     	unlock_super(sb);
156     	if (DQUOT_ALLOC_INODE(sb, inode))
157     	{
158     		sb->dq_op->drop(inode);
159     		inode->i_nlink = 0;
160     		iput(inode);
161     		*err = -EDQUOT;
162     		return NULL;
163     	}
164     
165     	*err = 0;
166     	return inode;
167     }
168