Blame view
fs/hpfs/namei.c
15.6 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 |
/* * linux/fs/hpfs/namei.c * * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999 * * adding & removing files & directories */ |
e8edc6e03 Detach sched.h fr... |
8 |
#include <linux/sched.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
#include "hpfs_fn.h" |
18bb1db3e switch vfs_mkdir(... |
10 |
static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
11 |
{ |
7e7742ee0 sanitize signedne... |
12 |
const unsigned char *name = dentry->d_name.name; |
1da177e4c Linux-2.6.12-rc2 |
13 14 15 16 17 18 19 20 21 22 23 24 |
unsigned len = dentry->d_name.len; struct quad_buffer_head qbh0; struct buffer_head *bh; struct hpfs_dirent *de; struct fnode *fnode; struct dnode *dnode; struct inode *result; fnode_secno fno; dnode_secno dno; int r; struct hpfs_dirent dee; int err; |
7e7742ee0 sanitize signedne... |
25 |
if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err; |
9a311b96c hpfs: remove the BKL |
26 |
hpfs_lock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 |
err = -ENOSPC; fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); if (!fnode) goto bail; |
7d23ce36e HPFS: Remove rema... |
31 |
dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0); |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 |
if (!dnode) goto bail1; memset(&dee, 0, sizeof dee); dee.directory = 1; if (!(mode & 0222)) dee.read_only = 1; /*dee.archive = 0;*/ dee.hidden = name[0] == '.'; |
0b69760be HPFS: Fix endiani... |
39 40 |
dee.fnode = cpu_to_le32(fno); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 44 45 46 47 |
result = new_inode(dir->i_sb); if (!result) goto bail2; hpfs_init_inode(result); result->i_ino = fno; hpfs_i(result)->i_parent_dir = dir->i_ino; hpfs_i(result)->i_dno = dno; |
0b69760be HPFS: Fix endiani... |
48 |
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 52 53 54 55 56 57 |
result->i_ctime.tv_nsec = 0; result->i_mtime.tv_nsec = 0; result->i_atime.tv_nsec = 0; hpfs_i(result)->i_ea_size = 0; result->i_mode |= S_IFDIR; result->i_op = &hpfs_dir_iops; result->i_fop = &hpfs_dir_ops; result->i_blocks = 4; result->i_size = 2048; |
bfe868486 filesystems: add ... |
58 |
set_nlink(result, 2); |
1da177e4c Linux-2.6.12-rc2 |
59 60 |
if (dee.read_only) result->i_mode &= ~0222; |
7d23ce36e HPFS: Remove rema... |
61 |
r = hpfs_add_dirent(dir, name, len, &dee); |
1da177e4c Linux-2.6.12-rc2 |
62 63 64 65 66 67 68 69 |
if (r == 1) goto bail3; if (r == -1) { err = -EEXIST; goto bail3; } fnode->len = len; memcpy(fnode->name, name, len > 15 ? 15 : len); |
0b69760be HPFS: Fix endiani... |
70 |
fnode->up = cpu_to_le32(dir->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 |
fnode->dirflag = 1; fnode->btree.n_free_nodes = 7; fnode->btree.n_used_nodes = 1; |
0b69760be HPFS: Fix endiani... |
74 75 76 |
fnode->btree.first_free = cpu_to_le16(0x14); fnode->u.external[0].disk_secno = cpu_to_le32(dno); fnode->u.external[0].file_secno = cpu_to_le32(-1); |
1da177e4c Linux-2.6.12-rc2 |
77 |
dnode->root_dnode = 1; |
0b69760be HPFS: Fix endiani... |
78 |
dnode->up = cpu_to_le32(fno); |
1da177e4c Linux-2.6.12-rc2 |
79 |
de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0); |
0b69760be HPFS: Fix endiani... |
80 |
de->creation_date = de->write_date = de->read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); |
1da177e4c Linux-2.6.12-rc2 |
81 82 83 |
if (!(mode & 0222)) de->read_only = 1; de->first = de->directory = 1; /*de->hidden = de->system = 0;*/ |
0b69760be HPFS: Fix endiani... |
84 |
de->fnode = cpu_to_le32(fno); |
1da177e4c Linux-2.6.12-rc2 |
85 86 87 88 |
mark_buffer_dirty(bh); brelse(bh); hpfs_mark_4buffers_dirty(&qbh0); hpfs_brelse4(&qbh0); |
d8c76e6f4 [PATCH] r/o bind ... |
89 |
inc_nlink(dir); |
1da177e4c Linux-2.6.12-rc2 |
90 |
insert_inode_hash(result); |
de395b8ac CRED: Wrap task c... |
91 92 |
if (result->i_uid != current_fsuid() || result->i_gid != current_fsgid() || |
1da177e4c Linux-2.6.12-rc2 |
93 |
result->i_mode != (mode | S_IFDIR)) { |
de395b8ac CRED: Wrap task c... |
94 95 |
result->i_uid = current_fsuid(); result->i_gid = current_fsgid(); |
1da177e4c Linux-2.6.12-rc2 |
96 97 98 99 |
result->i_mode = mode | S_IFDIR; hpfs_write_inode_nolock(result); } d_instantiate(dentry, result); |
9a311b96c hpfs: remove the BKL |
100 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
101 102 |
return 0; bail3: |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 106 107 108 109 110 |
iput(result); bail2: hpfs_brelse4(&qbh0); hpfs_free_dnode(dir->i_sb, dno); bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); bail: |
9a311b96c hpfs: remove the BKL |
111 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
112 113 |
return err; } |
4acdaf27e switch ->create()... |
114 |
static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd) |
1da177e4c Linux-2.6.12-rc2 |
115 |
{ |
7e7742ee0 sanitize signedne... |
116 |
const unsigned char *name = dentry->d_name.name; |
1da177e4c Linux-2.6.12-rc2 |
117 118 119 120 121 122 123 124 |
unsigned len = dentry->d_name.len; struct inode *result = NULL; struct buffer_head *bh; struct fnode *fnode; fnode_secno fno; int r; struct hpfs_dirent dee; int err; |
7e7742ee0 sanitize signedne... |
125 |
if ((err = hpfs_chk_name(name, &len))) |
1da177e4c Linux-2.6.12-rc2 |
126 |
return err==-ENOENT ? -EINVAL : err; |
9a311b96c hpfs: remove the BKL |
127 |
hpfs_lock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
128 129 130 131 132 133 134 135 |
err = -ENOSPC; fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); if (!fnode) goto bail; memset(&dee, 0, sizeof dee); if (!(mode & 0222)) dee.read_only = 1; dee.archive = 1; dee.hidden = name[0] == '.'; |
0b69760be HPFS: Fix endiani... |
136 137 |
dee.fnode = cpu_to_le32(fno); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); |
1da177e4c Linux-2.6.12-rc2 |
138 139 140 141 142 143 144 145 146 147 148 |
result = new_inode(dir->i_sb); if (!result) goto bail1; hpfs_init_inode(result); result->i_ino = fno; result->i_mode |= S_IFREG; result->i_mode &= ~0111; result->i_op = &hpfs_file_iops; result->i_fop = &hpfs_file_ops; |
bfe868486 filesystems: add ... |
149 |
set_nlink(result, 1); |
1da177e4c Linux-2.6.12-rc2 |
150 |
hpfs_i(result)->i_parent_dir = dir->i_ino; |
0b69760be HPFS: Fix endiani... |
151 |
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); |
1da177e4c Linux-2.6.12-rc2 |
152 153 154 155 156 157 158 159 160 161 |
result->i_ctime.tv_nsec = 0; result->i_mtime.tv_nsec = 0; result->i_atime.tv_nsec = 0; hpfs_i(result)->i_ea_size = 0; if (dee.read_only) result->i_mode &= ~0222; result->i_blocks = 1; result->i_size = 0; result->i_data.a_ops = &hpfs_aops; hpfs_i(result)->mmu_private = 0; |
7d23ce36e HPFS: Remove rema... |
162 |
r = hpfs_add_dirent(dir, name, len, &dee); |
1da177e4c Linux-2.6.12-rc2 |
163 164 165 166 167 168 169 170 |
if (r == 1) goto bail2; if (r == -1) { err = -EEXIST; goto bail2; } fnode->len = len; memcpy(fnode->name, name, len > 15 ? 15 : len); |
0b69760be HPFS: Fix endiani... |
171 |
fnode->up = cpu_to_le32(dir->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
172 173 174 175 |
mark_buffer_dirty(bh); brelse(bh); insert_inode_hash(result); |
de395b8ac CRED: Wrap task c... |
176 177 |
if (result->i_uid != current_fsuid() || result->i_gid != current_fsgid() || |
1da177e4c Linux-2.6.12-rc2 |
178 |
result->i_mode != (mode | S_IFREG)) { |
de395b8ac CRED: Wrap task c... |
179 180 |
result->i_uid = current_fsuid(); result->i_gid = current_fsgid(); |
1da177e4c Linux-2.6.12-rc2 |
181 182 183 184 |
result->i_mode = mode | S_IFREG; hpfs_write_inode_nolock(result); } d_instantiate(dentry, result); |
9a311b96c hpfs: remove the BKL |
185 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
186 187 188 |
return 0; bail2: |
1da177e4c Linux-2.6.12-rc2 |
189 190 191 192 193 |
iput(result); bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); bail: |
9a311b96c hpfs: remove the BKL |
194 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
195 196 |
return err; } |
1a67aafb5 switch ->mknod() ... |
197 |
static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) |
1da177e4c Linux-2.6.12-rc2 |
198 |
{ |
7e7742ee0 sanitize signedne... |
199 |
const unsigned char *name = dentry->d_name.name; |
1da177e4c Linux-2.6.12-rc2 |
200 201 202 203 204 205 206 207 |
unsigned len = dentry->d_name.len; struct buffer_head *bh; struct fnode *fnode; fnode_secno fno; int r; struct hpfs_dirent dee; struct inode *result = NULL; int err; |
7e7742ee0 sanitize signedne... |
208 |
if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err; |
1da177e4c Linux-2.6.12-rc2 |
209 210 211 |
if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM; if (!new_valid_dev(rdev)) return -EINVAL; |
9a311b96c hpfs: remove the BKL |
212 |
hpfs_lock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
213 214 215 216 217 218 219 220 |
err = -ENOSPC; fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); if (!fnode) goto bail; memset(&dee, 0, sizeof dee); if (!(mode & 0222)) dee.read_only = 1; dee.archive = 1; dee.hidden = name[0] == '.'; |
0b69760be HPFS: Fix endiani... |
221 222 |
dee.fnode = cpu_to_le32(fno); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); |
1da177e4c Linux-2.6.12-rc2 |
223 224 225 226 227 228 229 230 |
result = new_inode(dir->i_sb); if (!result) goto bail1; hpfs_init_inode(result); result->i_ino = fno; hpfs_i(result)->i_parent_dir = dir->i_ino; |
0b69760be HPFS: Fix endiani... |
231 |
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); |
1da177e4c Linux-2.6.12-rc2 |
232 233 234 235 |
result->i_ctime.tv_nsec = 0; result->i_mtime.tv_nsec = 0; result->i_atime.tv_nsec = 0; hpfs_i(result)->i_ea_size = 0; |
de395b8ac CRED: Wrap task c... |
236 237 |
result->i_uid = current_fsuid(); result->i_gid = current_fsgid(); |
bfe868486 filesystems: add ... |
238 |
set_nlink(result, 1); |
1da177e4c Linux-2.6.12-rc2 |
239 240 241 |
result->i_size = 0; result->i_blocks = 1; init_special_inode(result, mode, rdev); |
7d23ce36e HPFS: Remove rema... |
242 |
r = hpfs_add_dirent(dir, name, len, &dee); |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 246 247 248 249 250 |
if (r == 1) goto bail2; if (r == -1) { err = -EEXIST; goto bail2; } fnode->len = len; memcpy(fnode->name, name, len > 15 ? 15 : len); |
0b69760be HPFS: Fix endiani... |
251 |
fnode->up = cpu_to_le32(dir->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
252 253 254 255 256 257 |
mark_buffer_dirty(bh); insert_inode_hash(result); hpfs_write_inode_nolock(result); d_instantiate(dentry, result); |
1da177e4c Linux-2.6.12-rc2 |
258 |
brelse(bh); |
9a311b96c hpfs: remove the BKL |
259 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
260 261 |
return 0; bail2: |
1da177e4c Linux-2.6.12-rc2 |
262 263 264 265 266 |
iput(result); bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); bail: |
9a311b96c hpfs: remove the BKL |
267 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
268 269 270 271 272 |
return err; } static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink) { |
7e7742ee0 sanitize signedne... |
273 |
const unsigned char *name = dentry->d_name.name; |
1da177e4c Linux-2.6.12-rc2 |
274 275 276 277 278 279 280 281 |
unsigned len = dentry->d_name.len; struct buffer_head *bh; struct fnode *fnode; fnode_secno fno; int r; struct hpfs_dirent dee; struct inode *result; int err; |
7e7742ee0 sanitize signedne... |
282 |
if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err; |
9a311b96c hpfs: remove the BKL |
283 |
hpfs_lock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
284 |
if (hpfs_sb(dir->i_sb)->sb_eas < 2) { |
9a311b96c hpfs: remove the BKL |
285 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
286 287 288 289 290 291 292 293 294 |
return -EPERM; } err = -ENOSPC; fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); if (!fnode) goto bail; memset(&dee, 0, sizeof dee); dee.archive = 1; dee.hidden = name[0] == '.'; |
0b69760be HPFS: Fix endiani... |
295 296 |
dee.fnode = cpu_to_le32(fno); dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); |
1da177e4c Linux-2.6.12-rc2 |
297 298 299 300 301 302 303 |
result = new_inode(dir->i_sb); if (!result) goto bail1; result->i_ino = fno; hpfs_init_inode(result); hpfs_i(result)->i_parent_dir = dir->i_ino; |
0b69760be HPFS: Fix endiani... |
304 |
result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); |
1da177e4c Linux-2.6.12-rc2 |
305 306 307 308 309 |
result->i_ctime.tv_nsec = 0; result->i_mtime.tv_nsec = 0; result->i_atime.tv_nsec = 0; hpfs_i(result)->i_ea_size = 0; result->i_mode = S_IFLNK | 0777; |
de395b8ac CRED: Wrap task c... |
310 311 |
result->i_uid = current_fsuid(); result->i_gid = current_fsgid(); |
1da177e4c Linux-2.6.12-rc2 |
312 |
result->i_blocks = 1; |
bfe868486 filesystems: add ... |
313 |
set_nlink(result, 1); |
1da177e4c Linux-2.6.12-rc2 |
314 315 316 |
result->i_size = strlen(symlink); result->i_op = &page_symlink_inode_operations; result->i_data.a_ops = &hpfs_symlink_aops; |
7d23ce36e HPFS: Remove rema... |
317 |
r = hpfs_add_dirent(dir, name, len, &dee); |
1da177e4c Linux-2.6.12-rc2 |
318 319 320 321 322 323 324 325 |
if (r == 1) goto bail2; if (r == -1) { err = -EEXIST; goto bail2; } fnode->len = len; memcpy(fnode->name, name, len > 15 ? 15 : len); |
0b69760be HPFS: Fix endiani... |
326 |
fnode->up = cpu_to_le32(dir->i_ino); |
7e7742ee0 sanitize signedne... |
327 |
hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink)); |
1da177e4c Linux-2.6.12-rc2 |
328 329 330 331 332 333 334 |
mark_buffer_dirty(bh); brelse(bh); insert_inode_hash(result); hpfs_write_inode_nolock(result); d_instantiate(dentry, result); |
9a311b96c hpfs: remove the BKL |
335 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
336 337 |
return 0; bail2: |
1da177e4c Linux-2.6.12-rc2 |
338 339 340 341 342 |
iput(result); bail1: brelse(bh); hpfs_free_sectors(dir->i_sb, fno, 1); bail: |
9a311b96c hpfs: remove the BKL |
343 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
344 345 346 347 348 |
return err; } static int hpfs_unlink(struct inode *dir, struct dentry *dentry) { |
7e7742ee0 sanitize signedne... |
349 |
const unsigned char *name = dentry->d_name.name; |
1da177e4c Linux-2.6.12-rc2 |
350 351 352 353 354 |
unsigned len = dentry->d_name.len; struct quad_buffer_head qbh; struct hpfs_dirent *de; struct inode *inode = dentry->d_inode; dnode_secno dno; |
1da177e4c Linux-2.6.12-rc2 |
355 356 357 |
int r; int rep = 0; int err; |
9a311b96c hpfs: remove the BKL |
358 |
hpfs_lock(dir->i_sb); |
7e7742ee0 sanitize signedne... |
359 |
hpfs_adjust_length(name, &len); |
1da177e4c Linux-2.6.12-rc2 |
360 |
again: |
1da177e4c Linux-2.6.12-rc2 |
361 |
err = -ENOENT; |
7e7742ee0 sanitize signedne... |
362 |
de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); |
1da177e4c Linux-2.6.12-rc2 |
363 364 365 366 367 368 369 370 371 372 |
if (!de) goto out; err = -EPERM; if (de->first) goto out1; err = -EISDIR; if (de->directory) goto out1; |
1da177e4c Linux-2.6.12-rc2 |
373 374 375 376 377 378 379 380 381 382 383 |
r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); switch (r) { case 1: hpfs_error(dir->i_sb, "there was error when removing dirent"); err = -EFSERROR; break; case 2: /* no space for deleting, try to truncate file */ err = -ENOSPC; if (rep++) break; |
e21e7095a Don't mess with g... |
384 385 |
dentry_unhash(dentry); if (!d_unhashed(dentry)) { |
9a311b96c hpfs: remove the BKL |
386 |
hpfs_unlock(dir->i_sb); |
e21e7095a Don't mess with g... |
387 388 |
return -ENOSPC; } |
2830ba7f3 ->permission() sa... |
389 |
if (generic_permission(inode, MAY_WRITE) || |
1da177e4c Linux-2.6.12-rc2 |
390 391 |
!S_ISREG(inode->i_mode) || get_write_access(inode)) { |
1da177e4c Linux-2.6.12-rc2 |
392 393 394 |
d_rehash(dentry); } else { struct iattr newattrs; |
1da177e4c Linux-2.6.12-rc2 |
395 396 397 398 399 400 401 402 403 |
/*printk("HPFS: truncating file before delete. ");*/ newattrs.ia_size = 0; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; err = notify_change(dentry, &newattrs); put_write_access(inode); if (!err) goto again; } |
9a311b96c hpfs: remove the BKL |
404 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
405 406 |
return -ENOSPC; default: |
9a53c3a78 [PATCH] r/o bind ... |
407 |
drop_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
408 409 410 411 412 413 414 |
err = 0; } goto out; out1: hpfs_brelse4(&qbh); out: |
9a311b96c hpfs: remove the BKL |
415 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
416 417 418 419 420 |
return err; } static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) { |
7e7742ee0 sanitize signedne... |
421 |
const unsigned char *name = dentry->d_name.name; |
1da177e4c Linux-2.6.12-rc2 |
422 423 424 425 426 |
unsigned len = dentry->d_name.len; struct quad_buffer_head qbh; struct hpfs_dirent *de; struct inode *inode = dentry->d_inode; dnode_secno dno; |
1da177e4c Linux-2.6.12-rc2 |
427 428 429 |
int n_items = 0; int err; int r; |
7e7742ee0 sanitize signedne... |
430 |
hpfs_adjust_length(name, &len); |
9a311b96c hpfs: remove the BKL |
431 |
hpfs_lock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
432 |
err = -ENOENT; |
7e7742ee0 sanitize signedne... |
433 |
de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); |
1da177e4c Linux-2.6.12-rc2 |
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
if (!de) goto out; err = -EPERM; if (de->first) goto out1; err = -ENOTDIR; if (!de->directory) goto out1; hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items); err = -ENOTEMPTY; if (n_items) goto out1; |
1da177e4c Linux-2.6.12-rc2 |
449 450 451 452 453 454 455 456 457 458 |
r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); switch (r) { case 1: hpfs_error(dir->i_sb, "there was error when removing dirent"); err = -EFSERROR; break; case 2: err = -ENOSPC; break; default: |
9a53c3a78 [PATCH] r/o bind ... |
459 |
drop_nlink(dir); |
ce71ec368 [PATCH] r/o bind ... |
460 |
clear_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
461 462 463 464 465 466 |
err = 0; } goto out; out1: hpfs_brelse4(&qbh); out: |
9a311b96c hpfs: remove the BKL |
467 |
hpfs_unlock(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
468 469 470 471 472 473 474 475 476 477 478 479 |
return err; } static int hpfs_symlink_readpage(struct file *file, struct page *page) { char *link = kmap(page); struct inode *i = page->mapping->host; struct fnode *fnode; struct buffer_head *bh; int err; err = -EIO; |
9a311b96c hpfs: remove the BKL |
480 |
hpfs_lock(i->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
481 482 483 484 485 486 |
if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) goto fail; err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE); brelse(bh); if (err) goto fail; |
9a311b96c hpfs: remove the BKL |
487 |
hpfs_unlock(i->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
488 489 490 491 492 493 |
SetPageUptodate(page); kunmap(page); unlock_page(page); return 0; fail: |
9a311b96c hpfs: remove the BKL |
494 |
hpfs_unlock(i->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
495 496 497 498 499 |
SetPageError(page); kunmap(page); unlock_page(page); return err; } |
f5e54d6e5 [PATCH] mark addr... |
500 |
const struct address_space_operations hpfs_symlink_aops = { |
1da177e4c Linux-2.6.12-rc2 |
501 502 503 504 505 506 |
.readpage = hpfs_symlink_readpage }; static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { |
7e7742ee0 sanitize signedne... |
507 508 509 510 |
const unsigned char *old_name = old_dentry->d_name.name; unsigned old_len = old_dentry->d_name.len; const unsigned char *new_name = new_dentry->d_name.name; unsigned new_len = new_dentry->d_name.len; |
1da177e4c Linux-2.6.12-rc2 |
511 512 513 514 515 516 517 518 519 520 |
struct inode *i = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct quad_buffer_head qbh, qbh1; struct hpfs_dirent *dep, *nde; struct hpfs_dirent de; dnode_secno dno; int r; struct buffer_head *bh; struct fnode *fnode; int err; |
e4eaac06b vfs: push dentry_... |
521 |
|
7e7742ee0 sanitize signedne... |
522 |
if ((err = hpfs_chk_name(new_name, &new_len))) return err; |
1da177e4c Linux-2.6.12-rc2 |
523 |
err = 0; |
7e7742ee0 sanitize signedne... |
524 |
hpfs_adjust_length(old_name, &old_len); |
1da177e4c Linux-2.6.12-rc2 |
525 |
|
9a311b96c hpfs: remove the BKL |
526 |
hpfs_lock(i->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
527 |
/* order doesn't matter, due to VFS exclusion */ |
1da177e4c Linux-2.6.12-rc2 |
528 529 530 531 532 533 |
/* Erm? Moving over the empty non-busy directory is perfectly legal */ if (new_inode && S_ISDIR(new_inode->i_mode)) { err = -EINVAL; goto end1; } |
7e7742ee0 sanitize signedne... |
534 |
if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) { |
1da177e4c Linux-2.6.12-rc2 |
535 536 537 538 539 540 541 542 543 544 |
hpfs_error(i->i_sb, "lookup succeeded but map dirent failed"); err = -ENOENT; goto end1; } copy_de(&de, dep); de.hidden = new_name[0] == '.'; if (new_inode) { int r; if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) { |
7e7742ee0 sanitize signedne... |
545 |
if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) { |
ce71ec368 [PATCH] r/o bind ... |
546 |
clear_nlink(new_inode); |
1da177e4c Linux-2.6.12-rc2 |
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
copy_de(nde, &de); memcpy(nde->name, new_name, new_len); hpfs_mark_4buffers_dirty(&qbh1); hpfs_brelse4(&qbh1); goto end; } hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent"); err = -EFSERROR; goto end1; } err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0; goto end1; } if (new_dir == old_dir) hpfs_brelse4(&qbh); |
7d23ce36e HPFS: Remove rema... |
562 |
if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) { |
1da177e4c Linux-2.6.12-rc2 |
563 564 565 566 567 568 569 |
if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!"); err = r == 1 ? -ENOSPC : -EFSERROR; if (new_dir != old_dir) hpfs_brelse4(&qbh); goto end1; } if (new_dir == old_dir) |
7e7742ee0 sanitize signedne... |
570 |
if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) { |
1da177e4c Linux-2.6.12-rc2 |
571 572 573 574 575 576 |
hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2"); err = -ENOENT; goto end1; } if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) { |
1da177e4c Linux-2.6.12-rc2 |
577 578 579 580 |
hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent"); err = r == 2 ? -ENOSPC : -EFSERROR; goto end1; } |
7d23ce36e HPFS: Remove rema... |
581 |
|
1da177e4c Linux-2.6.12-rc2 |
582 583 584 |
end: hpfs_i(i)->i_parent_dir = new_dir->i_ino; if (S_ISDIR(i->i_mode)) { |
d8c76e6f4 [PATCH] r/o bind ... |
585 |
inc_nlink(new_dir); |
9a53c3a78 [PATCH] r/o bind ... |
586 |
drop_nlink(old_dir); |
1da177e4c Linux-2.6.12-rc2 |
587 588 |
} if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { |
0b69760be HPFS: Fix endiani... |
589 |
fnode->up = cpu_to_le32(new_dir->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
590 591 592 593 594 595 |
fnode->len = new_len; memcpy(fnode->name, new_name, new_len>15?15:new_len); if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len); mark_buffer_dirty(bh); brelse(bh); } |
1da177e4c Linux-2.6.12-rc2 |
596 |
end1: |
9a311b96c hpfs: remove the BKL |
597 |
hpfs_unlock(i->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
598 599 |
return err; } |
92e1d5be9 [PATCH] mark stru... |
600 |
const struct inode_operations hpfs_dir_iops = |
1da177e4c Linux-2.6.12-rc2 |
601 602 603 604 605 606 607 608 609 |
{ .create = hpfs_create, .lookup = hpfs_lookup, .unlink = hpfs_unlink, .symlink = hpfs_symlink, .mkdir = hpfs_mkdir, .rmdir = hpfs_rmdir, .mknod = hpfs_mknod, .rename = hpfs_rename, |
ca30bc995 [PATCH] hpfs: cle... |
610 |
.setattr = hpfs_setattr, |
1da177e4c Linux-2.6.12-rc2 |
611 |
}; |