Blame view
fs/ufs/namei.c
7.52 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * linux/fs/ufs/namei.c * |
b71034e5e [PATCH] ufs: dire... |
4 5 6 |
* Migration to usage of "page cache" on May 2006 by * Evgeniy Dushistov <dushistov@mail.ru> based on ext2 code base. * |
1da177e4c Linux-2.6.12-rc2 |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
* Copyright (C) 1998 * Daniel Pirkl <daniel.pirkl@email.cz> * Charles University, Faculty of Mathematics and Physics * * from * * linux/fs/ext2/namei.c * * Copyright (C) 1992, 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * * from * * linux/fs/minix/namei.c * * Copyright (C) 1991, 1992 Linus Torvalds * * Big-endian to little-endian byte-swapping/bitmaps by * David S. Miller (davem@caip.rutgers.edu), 1995 */ #include <linux/time.h> #include <linux/fs.h> |
e54205988 drop linux/ufs_fs... |
32 33 |
#include "ufs_fs.h" |
bcd6d4ecf ufs: move non-lay... |
34 |
#include "ufs.h" |
1da177e4c Linux-2.6.12-rc2 |
35 |
#include "util.h" |
1da177e4c Linux-2.6.12-rc2 |
36 37 38 39 40 41 42 |
static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) { int err = ufs_add_link(dentry, inode); if (!err) { d_instantiate(dentry, inode); return 0; } |
3257545e4 [PATCH] ufs: swit... |
43 |
inode_dec_link_count(inode); |
1da177e4c Linux-2.6.12-rc2 |
44 45 46 47 48 49 50 51 52 53 54 |
iput(inode); return err; } static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) { struct inode * inode = NULL; ino_t ino; if (dentry->d_name.len > UFS_MAXNAMLEN) return ERR_PTR(-ENAMETOOLONG); |
788257d61 ufs: remove the BKL |
55 |
lock_ufs(dir->i_sb); |
080497079 ufs: pass qstr in... |
56 |
ino = ufs_inode_by_name(dir, &dentry->d_name); |
642c937b4 ufs should use d_... |
57 |
if (ino) |
b55c460da iget: stop UFS fr... |
58 |
inode = ufs_iget(dir->i_sb, ino); |
788257d61 ufs: remove the BKL |
59 |
unlock_ufs(dir->i_sb); |
642c937b4 ufs should use d_... |
60 |
return d_splice_alias(inode, dentry); |
1da177e4c Linux-2.6.12-rc2 |
61 62 63 64 65 66 67 68 69 70 |
} /* * By the time this is called, we already have created * the directory cache entry for the new file, but it * is so far negative - it has no inode. * * If the create succeeds, we fill in the inode information * with d_instantiate(). */ |
4acdaf27e switch ->create()... |
71 |
static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, |
1da177e4c Linux-2.6.12-rc2 |
72 73 |
struct nameidata *nd) { |
abf5d15fd [PATCH] ufs: easy... |
74 75 76 77 78 |
struct inode *inode; int err; UFSD("BEGIN "); |
907f4554e dquot: move dquot... |
79 |
|
abf5d15fd [PATCH] ufs: easy... |
80 81 |
inode = ufs_new_inode(dir, mode); err = PTR_ERR(inode); |
1da177e4c Linux-2.6.12-rc2 |
82 83 84 85 86 |
if (!IS_ERR(inode)) { inode->i_op = &ufs_file_inode_operations; inode->i_fop = &ufs_file_operations; inode->i_mapping->a_ops = &ufs_aops; mark_inode_dirty(inode); |
788257d61 ufs: remove the BKL |
87 |
lock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
88 |
err = ufs_add_nondir(dentry, inode); |
788257d61 ufs: remove the BKL |
89 |
unlock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
90 |
} |
abf5d15fd [PATCH] ufs: easy... |
91 92 |
UFSD("END: err=%d ", err); |
1da177e4c Linux-2.6.12-rc2 |
93 94 |
return err; } |
1a67aafb5 switch ->mknod() ... |
95 |
static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) |
1da177e4c Linux-2.6.12-rc2 |
96 97 98 99 100 101 |
{ struct inode *inode; int err; if (!old_valid_dev(rdev)) return -EINVAL; |
907f4554e dquot: move dquot... |
102 |
|
1da177e4c Linux-2.6.12-rc2 |
103 104 105 106 |
inode = ufs_new_inode(dir, mode); err = PTR_ERR(inode); if (!IS_ERR(inode)) { init_special_inode(inode, mode, rdev); |
1da177e4c Linux-2.6.12-rc2 |
107 108 |
ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); mark_inode_dirty(inode); |
788257d61 ufs: remove the BKL |
109 |
lock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
110 |
err = ufs_add_nondir(dentry, inode); |
788257d61 ufs: remove the BKL |
111 |
unlock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
112 113 114 115 116 117 118 119 120 121 122 123 124 |
} return err; } static int ufs_symlink (struct inode * dir, struct dentry * dentry, const char * symname) { struct super_block * sb = dir->i_sb; int err = -ENAMETOOLONG; unsigned l = strlen(symname)+1; struct inode * inode; if (l > sb->s_blocksize) |
344fe7866 [PATCH] ufs: remo... |
125 |
goto out_notlocked; |
1da177e4c Linux-2.6.12-rc2 |
126 |
|
788257d61 ufs: remove the BKL |
127 |
lock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
128 129 130 131 132 133 134 |
inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); err = PTR_ERR(inode); if (IS_ERR(inode)) goto out; if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { /* slow symlink */ |
311b9549e ufs: add ufs spec... |
135 |
inode->i_op = &ufs_symlink_inode_operations; |
1da177e4c Linux-2.6.12-rc2 |
136 137 138 139 140 141 142 |
inode->i_mapping->a_ops = &ufs_aops; err = page_symlink(inode, symname, l); if (err) goto out_fail; } else { /* fast symlink */ inode->i_op = &ufs_fast_symlink_inode_operations; |
723be1f30 ufs: copy symlink... |
143 |
memcpy(UFS_I(inode)->i_u1.i_symlink, symname, l); |
1da177e4c Linux-2.6.12-rc2 |
144 145 146 147 148 149 |
inode->i_size = l-1; } mark_inode_dirty(inode); err = ufs_add_nondir(dentry, inode); out: |
788257d61 ufs: remove the BKL |
150 |
unlock_ufs(dir->i_sb); |
344fe7866 [PATCH] ufs: remo... |
151 |
out_notlocked: |
1da177e4c Linux-2.6.12-rc2 |
152 153 154 |
return err; out_fail: |
3257545e4 [PATCH] ufs: swit... |
155 |
inode_dec_link_count(inode); |
1da177e4c Linux-2.6.12-rc2 |
156 157 158 159 160 161 162 163 164 |
iput(inode); goto out; } static int ufs_link (struct dentry * old_dentry, struct inode * dir, struct dentry *dentry) { struct inode *inode = old_dentry->d_inode; int error; |
788257d61 ufs: remove the BKL |
165 |
lock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
166 |
if (inode->i_nlink >= UFS_LINK_MAX) { |
788257d61 ufs: remove the BKL |
167 |
unlock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
168 169 170 171 |
return -EMLINK; } inode->i_ctime = CURRENT_TIME_SEC; |
3257545e4 [PATCH] ufs: swit... |
172 |
inode_inc_link_count(inode); |
7de9c6ee3 new helper: ihold() |
173 |
ihold(inode); |
1da177e4c Linux-2.6.12-rc2 |
174 175 |
error = ufs_add_nondir(dentry, inode); |
788257d61 ufs: remove the BKL |
176 |
unlock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
177 178 |
return error; } |
18bb1db3e switch vfs_mkdir(... |
179 |
static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
180 181 182 183 184 185 |
{ struct inode * inode; int err = -EMLINK; if (dir->i_nlink >= UFS_LINK_MAX) goto out; |
788257d61 ufs: remove the BKL |
186 |
lock_ufs(dir->i_sb); |
3257545e4 [PATCH] ufs: swit... |
187 |
inode_inc_link_count(dir); |
1da177e4c Linux-2.6.12-rc2 |
188 189 190 191 192 193 194 195 |
inode = ufs_new_inode(dir, S_IFDIR|mode); err = PTR_ERR(inode); if (IS_ERR(inode)) goto out_dir; inode->i_op = &ufs_dir_inode_operations; inode->i_fop = &ufs_dir_operations; |
826843a34 [PATCH] ufs: dire... |
196 |
inode->i_mapping->a_ops = &ufs_aops; |
1da177e4c Linux-2.6.12-rc2 |
197 |
|
3257545e4 [PATCH] ufs: swit... |
198 |
inode_inc_link_count(inode); |
1da177e4c Linux-2.6.12-rc2 |
199 200 201 202 203 204 205 206 |
err = ufs_make_empty(inode, dir); if (err) goto out_fail; err = ufs_add_link(dentry, inode); if (err) goto out_fail; |
788257d61 ufs: remove the BKL |
207 |
unlock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
208 209 210 211 212 213 |
d_instantiate(dentry, inode); out: return err; out_fail: |
3257545e4 [PATCH] ufs: swit... |
214 215 |
inode_dec_link_count(inode); inode_dec_link_count(inode); |
1da177e4c Linux-2.6.12-rc2 |
216 217 |
iput (inode); out_dir: |
3257545e4 [PATCH] ufs: swit... |
218 |
inode_dec_link_count(dir); |
788257d61 ufs: remove the BKL |
219 |
unlock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
220 221 |
goto out; } |
b71034e5e [PATCH] ufs: dire... |
222 |
static int ufs_unlink(struct inode *dir, struct dentry *dentry) |
1da177e4c Linux-2.6.12-rc2 |
223 224 |
{ struct inode * inode = dentry->d_inode; |
b71034e5e [PATCH] ufs: dire... |
225 226 |
struct ufs_dir_entry *de; struct page *page; |
1da177e4c Linux-2.6.12-rc2 |
227 |
int err = -ENOENT; |
080497079 ufs: pass qstr in... |
228 |
de = ufs_find_entry(dir, &dentry->d_name, &page); |
1da177e4c Linux-2.6.12-rc2 |
229 230 |
if (!de) goto out; |
b71034e5e [PATCH] ufs: dire... |
231 |
err = ufs_delete_entry(dir, de, page); |
1da177e4c Linux-2.6.12-rc2 |
232 233 234 235 |
if (err) goto out; inode->i_ctime = dir->i_ctime; |
3257545e4 [PATCH] ufs: swit... |
236 |
inode_dec_link_count(inode); |
1da177e4c Linux-2.6.12-rc2 |
237 238 |
err = 0; out: |
1da177e4c Linux-2.6.12-rc2 |
239 240 241 242 243 244 245 |
return err; } static int ufs_rmdir (struct inode * dir, struct dentry *dentry) { struct inode * inode = dentry->d_inode; int err= -ENOTEMPTY; |
788257d61 ufs: remove the BKL |
246 |
lock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
247 248 249 250 |
if (ufs_empty_dir (inode)) { err = ufs_unlink(dir, dentry); if (!err) { inode->i_size = 0; |
3257545e4 [PATCH] ufs: swit... |
251 252 |
inode_dec_link_count(inode); inode_dec_link_count(dir); |
1da177e4c Linux-2.6.12-rc2 |
253 254 |
} } |
788257d61 ufs: remove the BKL |
255 |
unlock_ufs(dir->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
256 257 |
return err; } |
b71034e5e [PATCH] ufs: dire... |
258 259 |
static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) |
1da177e4c Linux-2.6.12-rc2 |
260 261 262 |
{ struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; |
b71034e5e [PATCH] ufs: dire... |
263 264 265 |
struct page *dir_page = NULL; struct ufs_dir_entry * dir_de = NULL; struct page *old_page; |
1da177e4c Linux-2.6.12-rc2 |
266 267 |
struct ufs_dir_entry *old_de; int err = -ENOENT; |
080497079 ufs: pass qstr in... |
268 |
old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
1da177e4c Linux-2.6.12-rc2 |
269 270 271 272 273 |
if (!old_de) goto out; if (S_ISDIR(old_inode->i_mode)) { err = -EIO; |
b71034e5e [PATCH] ufs: dire... |
274 |
dir_de = ufs_dotdot(old_inode, &dir_page); |
1da177e4c Linux-2.6.12-rc2 |
275 276 277 278 279 |
if (!dir_de) goto out_old; } if (new_inode) { |
b71034e5e [PATCH] ufs: dire... |
280 |
struct page *new_page; |
1da177e4c Linux-2.6.12-rc2 |
281 282 283 |
struct ufs_dir_entry *new_de; err = -ENOTEMPTY; |
b71034e5e [PATCH] ufs: dire... |
284 |
if (dir_de && !ufs_empty_dir(new_inode)) |
1da177e4c Linux-2.6.12-rc2 |
285 |
goto out_dir; |
b71034e5e [PATCH] ufs: dire... |
286 |
|
1da177e4c Linux-2.6.12-rc2 |
287 |
err = -ENOENT; |
080497079 ufs: pass qstr in... |
288 |
new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); |
1da177e4c Linux-2.6.12-rc2 |
289 290 |
if (!new_de) goto out_dir; |
b71034e5e [PATCH] ufs: dire... |
291 |
ufs_set_link(new_dir, new_de, new_page, old_inode); |
1da177e4c Linux-2.6.12-rc2 |
292 293 |
new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) |
9a53c3a78 [PATCH] r/o bind ... |
294 |
drop_nlink(new_inode); |
3257545e4 [PATCH] ufs: swit... |
295 |
inode_dec_link_count(new_inode); |
1da177e4c Linux-2.6.12-rc2 |
296 297 298 299 300 301 |
} else { if (dir_de) { err = -EMLINK; if (new_dir->i_nlink >= UFS_LINK_MAX) goto out_dir; } |
1da177e4c Linux-2.6.12-rc2 |
302 |
err = ufs_add_link(new_dentry, old_inode); |
37750cdda ufs: i_nlink race... |
303 |
if (err) |
1da177e4c Linux-2.6.12-rc2 |
304 |
goto out_dir; |
1da177e4c Linux-2.6.12-rc2 |
305 |
if (dir_de) |
3257545e4 [PATCH] ufs: swit... |
306 |
inode_inc_link_count(new_dir); |
1da177e4c Linux-2.6.12-rc2 |
307 |
} |
b71034e5e [PATCH] ufs: dire... |
308 309 310 |
/* * Like most other Unix systems, set the ctime for inodes on a * rename. |
b71034e5e [PATCH] ufs: dire... |
311 312 |
*/ old_inode->i_ctime = CURRENT_TIME_SEC; |
1da177e4c Linux-2.6.12-rc2 |
313 |
|
b71034e5e [PATCH] ufs: dire... |
314 |
ufs_delete_entry(old_dir, old_de, old_page); |
37750cdda ufs: i_nlink race... |
315 |
mark_inode_dirty(old_inode); |
1da177e4c Linux-2.6.12-rc2 |
316 317 |
if (dir_de) { |
b71034e5e [PATCH] ufs: dire... |
318 |
ufs_set_link(old_inode, dir_de, dir_page, new_dir); |
3257545e4 [PATCH] ufs: swit... |
319 |
inode_dec_link_count(old_dir); |
1da177e4c Linux-2.6.12-rc2 |
320 |
} |
1da177e4c Linux-2.6.12-rc2 |
321 |
return 0; |
b71034e5e [PATCH] ufs: dire... |
322 |
|
1da177e4c Linux-2.6.12-rc2 |
323 |
out_dir: |
b71034e5e [PATCH] ufs: dire... |
324 325 326 327 |
if (dir_de) { kunmap(dir_page); page_cache_release(dir_page); } |
1da177e4c Linux-2.6.12-rc2 |
328 |
out_old: |
b71034e5e [PATCH] ufs: dire... |
329 330 |
kunmap(old_page); page_cache_release(old_page); |
1da177e4c Linux-2.6.12-rc2 |
331 |
out: |
1da177e4c Linux-2.6.12-rc2 |
332 333 |
return err; } |
c5ef1c42c [PATCH] mark stru... |
334 |
const struct inode_operations ufs_dir_inode_operations = { |
1da177e4c Linux-2.6.12-rc2 |
335 336 337 338 339 340 341 342 343 344 |
.create = ufs_create, .lookup = ufs_lookup, .link = ufs_link, .unlink = ufs_unlink, .symlink = ufs_symlink, .mkdir = ufs_mkdir, .rmdir = ufs_rmdir, .mknod = ufs_mknod, .rename = ufs_rename, }; |