OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [fs/] [ufs/] [namei.c] - Blame information for rev 19

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.