- T(YAFFS_TRACE_OS, (TSTR("yaffs_readdir: starting at %d\n"), (int)offset));
-
- if (offset == 0) {
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_readdir: entry . ino %d \n"),
- (int)inode->i_ino));
- yaffs_gross_unlock(dev);
- if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0){
- yaffs_gross_lock(dev);
- goto out;
- }
- yaffs_gross_lock(dev);
- offset++;
- f->f_pos++;
- }
- if (offset == 1) {
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_readdir: entry .. ino %d \n"),
- (int)f->f_dentry->d_parent->d_inode->i_ino));
- yaffs_gross_unlock(dev);
- if (filldir(dirent, "..", 2, offset,
- f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0){
- yaffs_gross_lock(dev);
- goto out;
- }
- yaffs_gross_lock(dev);
- offset++;
- f->f_pos++;
- }
-
- curoffs = 1;
-
- /* If the directory has changed since the open or last call to
- readdir, rewind to after the 2 canned entries. */
- if (f->f_version != inode->i_version) {
- offset = 2;
- f->f_pos = offset;
- f->f_version = inode->i_version;
- }
-
- while(sc->next_return){
- curoffs++;
- l = sc->next_return;
- if (curoffs >= offset) {
- int this_inode = yaffs_get_obj_inode(l);
- int this_type = yaffs_get_obj_type(l);
-
- yaffs_get_obj_name(l, name,
- YAFFS_MAX_NAME_LENGTH + 1);
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_readdir: %s inode %d\n"),
- name, yaffs_get_obj_inode(l)));
-
- yaffs_gross_unlock(dev);
-
- if (filldir(dirent,
- name,
- strlen(name),
- offset,
- this_inode,
- this_type) < 0){
- yaffs_gross_lock(dev);
- goto out;
- }
-
- yaffs_gross_lock(dev);
-
- offset++;
- f->f_pos++;
- }
- yaffs_search_advance(sc);
- }
-
-out:
- yaffs_search_end(sc);
- yaffs_dev_to_lc(dev)->readdir_process = NULL;
- yaffs_gross_unlock(dev);
-
- return ret_val;
-}
-
-
-
-/*
- * File creation. Allocate an inode, and we're done..
- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
-#define YCRED(x) x
-#else
-#define YCRED(x) (x->cred)
-#endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
- dev_t rdev)
-#else
-static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
- int rdev)
-#endif
-{
- struct inode *inode;
-
- yaffs_obj_t *obj = NULL;
- yaffs_dev_t *dev;
-
- yaffs_obj_t *parent = yaffs_inode_to_obj(dir);
-
- int error = -ENOSPC;
- uid_t uid = YCRED(current)->fsuid;
- gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-
- if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
- mode |= S_ISGID;
-
- if (parent) {
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_mknod: parent object %d type %d\n"),
- parent->obj_id, parent->variant_type));
- } else {
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_mknod: could not get parent object\n")));
- return -EPERM;
- }
-
- T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making oject for %s, "
- "mode %x dev %x\n"),
- dentry->d_name.name, mode, rdev));
-
- dev = parent->my_dev;
-
- yaffs_gross_lock(dev);
-
- switch (mode & S_IFMT) {
- default:
- /* Special (socket, fifo, device...) */
- T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making special\n")));
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- obj = yaffs_create_special(parent, dentry->d_name.name, mode, uid,
- gid, old_encode_dev(rdev));
-#else
- obj = yaffs_create_special(parent, dentry->d_name.name, mode, uid,
- gid, rdev);
-#endif
- break;
- case S_IFREG: /* file */
- T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making file\n")));
- obj = yaffs_create_file(parent, dentry->d_name.name, mode, uid,
- gid);
- break;
- case S_IFDIR: /* directory */
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_mknod: making directory\n")));
- obj = yaffs_create_dir(parent, dentry->d_name.name, mode,
- uid, gid);
- break;
- case S_IFLNK: /* symlink */
- T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making symlink\n")));
- obj = NULL; /* Do we ever get here? */
- break;
- }
-
- /* Can not call yaffs_get_inode() with gross lock held */
- yaffs_gross_unlock(dev);
-
- if (obj) {
- inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
- d_instantiate(dentry, inode);
- update_dir_time(dir);
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_mknod created object %d count = %d\n"),
- obj->obj_id, atomic_read(&inode->i_count)));
- error = 0;
- yaffs_fill_inode_from_obj(dir,parent);
- } else {
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_mknod failed making object\n")));
- error = -ENOMEM;
- }
-
- return error;
-}
-
-static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
- int ret_val;
- T(YAFFS_TRACE_OS, (TSTR("yaffs_mkdir\n")));
- ret_val = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
- return ret_val;
-}
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
- struct nameidata *n)
-#else
-static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
-#endif
-{
- T(YAFFS_TRACE_OS,(TSTR("yaffs_create\n")));
- return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
-}
-
-static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
-{
- int ret_val;
-
- yaffs_dev_t *dev;
- yaffs_obj_t *obj;
-
- T(YAFFS_TRACE_OS,
- (TSTR("yaffs_unlink %d:%s\n"),
- (int)(dir->i_ino),
- dentry->d_name.name));
- obj = yaffs_inode_to_obj(dir);
- dev = obj->my_dev;
-
- yaffs_gross_lock(dev);
-
- ret_val = yaffs_unlinker(obj, dentry->d_name.name);
-
- if (ret_val == YAFFS_OK) {
- dentry->d_inode->i_nlink--;
- dir->i_version++;
- yaffs_gross_unlock(dev);
- mark_inode_dirty(dentry->d_inode);
- update_dir_time(dir);
- return 0;
- }
- yaffs_gross_unlock(dev);
- return -ENOTEMPTY;
-}
-
-/*
- * Create a link...
- */
-static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
- struct dentry *dentry)
-{
- struct inode *inode = old_dentry->d_inode;
- yaffs_obj_t *obj = NULL;
- yaffs_obj_t *link = NULL;
- yaffs_dev_t *dev;
-
- T(YAFFS_TRACE_OS, (TSTR("yaffs_link\n")));
-
- obj = yaffs_inode_to_obj(inode);
- dev = obj->my_dev;
-
- yaffs_gross_lock(dev);
-
- if (!S_ISDIR(inode->i_mode)) /* Don't link directories */
- link = yaffs_link_obj(yaffs_inode_to_obj(dir), dentry->d_name.name,
- obj);