Commit 69102e9b4b61f56a26717659ec2e572a6b18458d
1 parent
810c1b2e48
Exists in
master
and in
39 other branches
hfs: fix rename() over non-empty directory
merge hfs_unlink() and hfs_rmdir(), while we are at it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 13 additions and 37 deletions Side-by-side Diff
fs/hfs/dir.c
... | ... | @@ -238,46 +238,22 @@ |
238 | 238 | } |
239 | 239 | |
240 | 240 | /* |
241 | - * hfs_unlink() | |
241 | + * hfs_remove() | |
242 | 242 | * |
243 | - * This is the unlink() entry in the inode_operations structure for | |
244 | - * regular HFS directories. The purpose is to delete an existing | |
245 | - * file, given the inode for the parent directory and the name | |
246 | - * (and its length) of the existing file. | |
247 | - */ | |
248 | -static int hfs_unlink(struct inode *dir, struct dentry *dentry) | |
249 | -{ | |
250 | - struct inode *inode; | |
251 | - int res; | |
252 | - | |
253 | - inode = dentry->d_inode; | |
254 | - res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); | |
255 | - if (res) | |
256 | - return res; | |
257 | - | |
258 | - drop_nlink(inode); | |
259 | - hfs_delete_inode(inode); | |
260 | - inode->i_ctime = CURRENT_TIME_SEC; | |
261 | - mark_inode_dirty(inode); | |
262 | - | |
263 | - return res; | |
264 | -} | |
265 | - | |
266 | -/* | |
267 | - * hfs_rmdir() | |
243 | + * This serves as both unlink() and rmdir() in the inode_operations | |
244 | + * structure for regular HFS directories. The purpose is to delete | |
245 | + * an existing child, given the inode for the parent directory and | |
246 | + * the name (and its length) of the existing directory. | |
268 | 247 | * |
269 | - * This is the rmdir() entry in the inode_operations structure for | |
270 | - * regular HFS directories. The purpose is to delete an existing | |
271 | - * directory, given the inode for the parent directory and the name | |
272 | - * (and its length) of the existing directory. | |
248 | + * HFS does not have hardlinks, so both rmdir and unlink set the | |
249 | + * link count to 0. The only difference is the emptiness check. | |
273 | 250 | */ |
274 | -static int hfs_rmdir(struct inode *dir, struct dentry *dentry) | |
251 | +static int hfs_remove(struct inode *dir, struct dentry *dentry) | |
275 | 252 | { |
276 | - struct inode *inode; | |
253 | + struct inode *inode = dentry->d_inode; | |
277 | 254 | int res; |
278 | 255 | |
279 | - inode = dentry->d_inode; | |
280 | - if (inode->i_size != 2) | |
256 | + if (S_ISDIR(inode->i_mode) && inode->i_size != 2) | |
281 | 257 | return -ENOTEMPTY; |
282 | 258 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); |
283 | 259 | if (res) |
... | ... | @@ -307,7 +283,7 @@ |
307 | 283 | |
308 | 284 | /* Unlink destination if it already exists */ |
309 | 285 | if (new_dentry->d_inode) { |
310 | - res = hfs_unlink(new_dir, new_dentry); | |
286 | + res = hfs_remove(new_dir, new_dentry); | |
311 | 287 | if (res) |
312 | 288 | return res; |
313 | 289 | } |
314 | 290 | |
... | ... | @@ -332,9 +308,9 @@ |
332 | 308 | const struct inode_operations hfs_dir_inode_operations = { |
333 | 309 | .create = hfs_create, |
334 | 310 | .lookup = hfs_lookup, |
335 | - .unlink = hfs_unlink, | |
311 | + .unlink = hfs_remove, | |
336 | 312 | .mkdir = hfs_mkdir, |
337 | - .rmdir = hfs_rmdir, | |
313 | + .rmdir = hfs_remove, | |
338 | 314 | .rename = hfs_rename, |
339 | 315 | .setattr = hfs_inode_setattr, |
340 | 316 | }; |