- yaffs_touch_super(dev);
-
- yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_file_write: %d(%x) bytes written",
- (unsigned)n, (unsigned)n);
-
- if (n_written > 0) {
- ipos += n_written;
- *pos = ipos;
- if (ipos > inode->i_size) {
- inode->i_size = ipos;
- inode->i_blocks = (ipos + 511) >> 9;
-
- yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_file_write size updated to %lld bytes, %d blocks",
- ipos, (int)(inode->i_blocks));
- }
-
- }
- yaffs_gross_unlock(dev);
- return (n_written == 0) && (n > 0) ? -ENOSPC : n_written;
-}
-
-/* Space holding and freeing is done to ensure we have space available for write_begin/end */
-/* For now we just assume few parallel writes and check against a small number. */
-/* Todo: need to do this with a counter to handle parallel reads better */
-
-static ssize_t yaffs_hold_space(struct file *f)
-{
- struct yaffs_obj *obj;
- struct yaffs_dev *dev;
-
- int n_free_chunks;
-
- obj = yaffs_dentry_to_obj(f->f_dentry);
-
- dev = obj->my_dev;
-
- yaffs_gross_lock(dev);
-
- n_free_chunks = yaffs_get_n_free_chunks(dev);
-
- yaffs_gross_unlock(dev);
-
- return (n_free_chunks > 20) ? 1 : 0;
-}
-
-static void yaffs_release_space(struct file *f)
-{
- struct yaffs_obj *obj;
- struct yaffs_dev *dev;
-
- obj = yaffs_dentry_to_obj(f->f_dentry);
-
- dev = obj->my_dev;
-
- yaffs_gross_lock(dev);
-
- yaffs_gross_unlock(dev);
-}
-
-static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
-{
- struct yaffs_obj *obj;
- struct yaffs_dev *dev;
- struct yaffs_search_context *sc;
- struct inode *inode = f->f_dentry->d_inode;
- unsigned long offset, curoffs;
- struct yaffs_obj *l;
- int ret_val = 0;
-
- char name[YAFFS_MAX_NAME_LENGTH + 1];
-
- obj = yaffs_dentry_to_obj(f->f_dentry);
- dev = obj->my_dev;
-
- yaffs_gross_lock(dev);
-
- yaffs_dev_to_lc(dev)->readdir_process = current;
-
- offset = f->f_pos;
-
- sc = yaffs_new_search(obj);
- if (!sc) {
- ret_val = -ENOMEM;
- goto out;
- }
-
- yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_readdir: starting at %d", (int)offset);
-
- if (offset == 0) {
- yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_readdir: entry . ino %d",
- (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) {
- yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_readdir: entry .. ino %d",
- (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);
- yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_readdir: %s inode %d",
- 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;
-
- struct yaffs_obj *obj = NULL;
- struct yaffs_dev *dev;
-
- struct yaffs_obj *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;