diff options
Diffstat (limited to 'fs/ufs/namei.c')
-rw-r--r-- | fs/ufs/namei.c | 79 |
1 files changed, 33 insertions, 46 deletions
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index f773deb1d2e3..47966554317c 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -56,11 +56,9 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, unsi | |||
56 | if (dentry->d_name.len > UFS_MAXNAMLEN) | 56 | if (dentry->d_name.len > UFS_MAXNAMLEN) |
57 | return ERR_PTR(-ENAMETOOLONG); | 57 | return ERR_PTR(-ENAMETOOLONG); |
58 | 58 | ||
59 | lock_ufs(dir->i_sb); | ||
60 | ino = ufs_inode_by_name(dir, &dentry->d_name); | 59 | ino = ufs_inode_by_name(dir, &dentry->d_name); |
61 | if (ino) | 60 | if (ino) |
62 | inode = ufs_iget(dir->i_sb, ino); | 61 | inode = ufs_iget(dir->i_sb, ino); |
63 | unlock_ufs(dir->i_sb); | ||
64 | return d_splice_alias(inode, dentry); | 62 | return d_splice_alias(inode, dentry); |
65 | } | 63 | } |
66 | 64 | ||
@@ -76,24 +74,16 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, | |||
76 | bool excl) | 74 | bool excl) |
77 | { | 75 | { |
78 | struct inode *inode; | 76 | struct inode *inode; |
79 | int err; | ||
80 | |||
81 | UFSD("BEGIN\n"); | ||
82 | 77 | ||
83 | inode = ufs_new_inode(dir, mode); | 78 | inode = ufs_new_inode(dir, mode); |
84 | err = PTR_ERR(inode); | 79 | if (IS_ERR(inode)) |
80 | return PTR_ERR(inode); | ||
85 | 81 | ||
86 | if (!IS_ERR(inode)) { | 82 | inode->i_op = &ufs_file_inode_operations; |
87 | inode->i_op = &ufs_file_inode_operations; | 83 | inode->i_fop = &ufs_file_operations; |
88 | inode->i_fop = &ufs_file_operations; | 84 | inode->i_mapping->a_ops = &ufs_aops; |
89 | inode->i_mapping->a_ops = &ufs_aops; | 85 | mark_inode_dirty(inode); |
90 | mark_inode_dirty(inode); | 86 | return ufs_add_nondir(dentry, inode); |
91 | lock_ufs(dir->i_sb); | ||
92 | err = ufs_add_nondir(dentry, inode); | ||
93 | unlock_ufs(dir->i_sb); | ||
94 | } | ||
95 | UFSD("END: err=%d\n", err); | ||
96 | return err; | ||
97 | } | 87 | } |
98 | 88 | ||
99 | static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) | 89 | static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) |
@@ -110,9 +100,7 @@ static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev | |||
110 | init_special_inode(inode, mode, rdev); | 100 | init_special_inode(inode, mode, rdev); |
111 | ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); | 101 | ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); |
112 | mark_inode_dirty(inode); | 102 | mark_inode_dirty(inode); |
113 | lock_ufs(dir->i_sb); | ||
114 | err = ufs_add_nondir(dentry, inode); | 103 | err = ufs_add_nondir(dentry, inode); |
115 | unlock_ufs(dir->i_sb); | ||
116 | } | 104 | } |
117 | return err; | 105 | return err; |
118 | } | 106 | } |
@@ -121,19 +109,18 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
121 | const char * symname) | 109 | const char * symname) |
122 | { | 110 | { |
123 | struct super_block * sb = dir->i_sb; | 111 | struct super_block * sb = dir->i_sb; |
124 | int err = -ENAMETOOLONG; | 112 | int err; |
125 | unsigned l = strlen(symname)+1; | 113 | unsigned l = strlen(symname)+1; |
126 | struct inode * inode; | 114 | struct inode * inode; |
127 | 115 | ||
128 | if (l > sb->s_blocksize) | 116 | if (l > sb->s_blocksize) |
129 | goto out_notlocked; | 117 | return -ENAMETOOLONG; |
130 | 118 | ||
131 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 119 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
132 | err = PTR_ERR(inode); | 120 | err = PTR_ERR(inode); |
133 | if (IS_ERR(inode)) | 121 | if (IS_ERR(inode)) |
134 | goto out_notlocked; | 122 | return err; |
135 | 123 | ||
136 | lock_ufs(dir->i_sb); | ||
137 | if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { | 124 | if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { |
138 | /* slow symlink */ | 125 | /* slow symlink */ |
139 | inode->i_op = &ufs_symlink_inode_operations; | 126 | inode->i_op = &ufs_symlink_inode_operations; |
@@ -150,17 +137,13 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
150 | } | 137 | } |
151 | mark_inode_dirty(inode); | 138 | mark_inode_dirty(inode); |
152 | 139 | ||
153 | err = ufs_add_nondir(dentry, inode); | 140 | return ufs_add_nondir(dentry, inode); |
154 | out: | ||
155 | unlock_ufs(dir->i_sb); | ||
156 | out_notlocked: | ||
157 | return err; | ||
158 | 141 | ||
159 | out_fail: | 142 | out_fail: |
160 | inode_dec_link_count(inode); | 143 | inode_dec_link_count(inode); |
161 | unlock_new_inode(inode); | 144 | unlock_new_inode(inode); |
162 | iput(inode); | 145 | iput(inode); |
163 | goto out; | 146 | return err; |
164 | } | 147 | } |
165 | 148 | ||
166 | static int ufs_link (struct dentry * old_dentry, struct inode * dir, | 149 | static int ufs_link (struct dentry * old_dentry, struct inode * dir, |
@@ -169,14 +152,16 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, | |||
169 | struct inode *inode = d_inode(old_dentry); | 152 | struct inode *inode = d_inode(old_dentry); |
170 | int error; | 153 | int error; |
171 | 154 | ||
172 | lock_ufs(dir->i_sb); | ||
173 | |||
174 | inode->i_ctime = CURRENT_TIME_SEC; | 155 | inode->i_ctime = CURRENT_TIME_SEC; |
175 | inode_inc_link_count(inode); | 156 | inode_inc_link_count(inode); |
176 | ihold(inode); | 157 | ihold(inode); |
177 | 158 | ||
178 | error = ufs_add_nondir(dentry, inode); | 159 | error = ufs_add_link(dentry, inode); |
179 | unlock_ufs(dir->i_sb); | 160 | if (error) { |
161 | inode_dec_link_count(inode); | ||
162 | iput(inode); | ||
163 | } else | ||
164 | d_instantiate(dentry, inode); | ||
180 | return error; | 165 | return error; |
181 | } | 166 | } |
182 | 167 | ||
@@ -185,9 +170,12 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | |||
185 | struct inode * inode; | 170 | struct inode * inode; |
186 | int err; | 171 | int err; |
187 | 172 | ||
173 | inode_inc_link_count(dir); | ||
174 | |||
188 | inode = ufs_new_inode(dir, S_IFDIR|mode); | 175 | inode = ufs_new_inode(dir, S_IFDIR|mode); |
176 | err = PTR_ERR(inode); | ||
189 | if (IS_ERR(inode)) | 177 | if (IS_ERR(inode)) |
190 | return PTR_ERR(inode); | 178 | goto out_dir; |
191 | 179 | ||
192 | inode->i_op = &ufs_dir_inode_operations; | 180 | inode->i_op = &ufs_dir_inode_operations; |
193 | inode->i_fop = &ufs_dir_operations; | 181 | inode->i_fop = &ufs_dir_operations; |
@@ -195,9 +183,6 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | |||
195 | 183 | ||
196 | inode_inc_link_count(inode); | 184 | inode_inc_link_count(inode); |
197 | 185 | ||
198 | lock_ufs(dir->i_sb); | ||
199 | inode_inc_link_count(dir); | ||
200 | |||
201 | err = ufs_make_empty(inode, dir); | 186 | err = ufs_make_empty(inode, dir); |
202 | if (err) | 187 | if (err) |
203 | goto out_fail; | 188 | goto out_fail; |
@@ -205,20 +190,19 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | |||
205 | err = ufs_add_link(dentry, inode); | 190 | err = ufs_add_link(dentry, inode); |
206 | if (err) | 191 | if (err) |
207 | goto out_fail; | 192 | goto out_fail; |
208 | unlock_ufs(dir->i_sb); | ||
209 | 193 | ||
194 | unlock_new_inode(inode); | ||
210 | d_instantiate(dentry, inode); | 195 | d_instantiate(dentry, inode); |
211 | out: | 196 | return 0; |
212 | return err; | ||
213 | 197 | ||
214 | out_fail: | 198 | out_fail: |
215 | inode_dec_link_count(inode); | 199 | inode_dec_link_count(inode); |
216 | inode_dec_link_count(inode); | 200 | inode_dec_link_count(inode); |
217 | unlock_new_inode(inode); | 201 | unlock_new_inode(inode); |
218 | iput (inode); | 202 | iput (inode); |
203 | out_dir: | ||
219 | inode_dec_link_count(dir); | 204 | inode_dec_link_count(dir); |
220 | unlock_ufs(dir->i_sb); | 205 | return err; |
221 | goto out; | ||
222 | } | 206 | } |
223 | 207 | ||
224 | static int ufs_unlink(struct inode *dir, struct dentry *dentry) | 208 | static int ufs_unlink(struct inode *dir, struct dentry *dentry) |
@@ -248,7 +232,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
248 | struct inode * inode = d_inode(dentry); | 232 | struct inode * inode = d_inode(dentry); |
249 | int err= -ENOTEMPTY; | 233 | int err= -ENOTEMPTY; |
250 | 234 | ||
251 | lock_ufs(dir->i_sb); | ||
252 | if (ufs_empty_dir (inode)) { | 235 | if (ufs_empty_dir (inode)) { |
253 | err = ufs_unlink(dir, dentry); | 236 | err = ufs_unlink(dir, dentry); |
254 | if (!err) { | 237 | if (!err) { |
@@ -257,7 +240,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
257 | inode_dec_link_count(dir); | 240 | inode_dec_link_count(dir); |
258 | } | 241 | } |
259 | } | 242 | } |
260 | unlock_ufs(dir->i_sb); | ||
261 | return err; | 243 | return err; |
262 | } | 244 | } |
263 | 245 | ||
@@ -295,7 +277,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
295 | new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); | 277 | new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); |
296 | if (!new_de) | 278 | if (!new_de) |
297 | goto out_dir; | 279 | goto out_dir; |
298 | ufs_set_link(new_dir, new_de, new_page, old_inode); | 280 | ufs_set_link(new_dir, new_de, new_page, old_inode, 1); |
299 | new_inode->i_ctime = CURRENT_TIME_SEC; | 281 | new_inode->i_ctime = CURRENT_TIME_SEC; |
300 | if (dir_de) | 282 | if (dir_de) |
301 | drop_nlink(new_inode); | 283 | drop_nlink(new_inode); |
@@ -318,7 +300,12 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
318 | mark_inode_dirty(old_inode); | 300 | mark_inode_dirty(old_inode); |
319 | 301 | ||
320 | if (dir_de) { | 302 | if (dir_de) { |
321 | ufs_set_link(old_inode, dir_de, dir_page, new_dir); | 303 | if (old_dir != new_dir) |
304 | ufs_set_link(old_inode, dir_de, dir_page, new_dir, 0); | ||
305 | else { | ||
306 | kunmap(dir_page); | ||
307 | page_cache_release(dir_page); | ||
308 | } | ||
322 | inode_dec_link_count(old_dir); | 309 | inode_dec_link_count(old_dir); |
323 | } | 310 | } |
324 | return 0; | 311 | return 0; |