tizen: Use unique directory prefix for baselibs packages
[platform/kernel/linux-rpi.git] / fs / libfs.c
index 37f2d34..dc0f751 100644 (file)
@@ -396,6 +396,8 @@ static loff_t offset_dir_llseek(struct file *file, loff_t offset, int whence)
                return -EINVAL;
        }
 
+       /* In this case, ->private_data is protected by f_pos_lock */
+       file->private_data = NULL;
        return vfs_setpos(file, offset, U32_MAX);
 }
 
@@ -425,7 +427,7 @@ static bool offset_dir_emit(struct dir_context *ctx, struct dentry *dentry)
                          inode->i_ino, fs_umode_to_dtype(inode->i_mode));
 }
 
-static void offset_iterate_dir(struct inode *inode, struct dir_context *ctx)
+static void *offset_iterate_dir(struct inode *inode, struct dir_context *ctx)
 {
        struct offset_ctx *so_ctx = inode->i_op->get_offset_ctx(inode);
        XA_STATE(xas, &so_ctx->xa, ctx->pos);
@@ -434,7 +436,7 @@ static void offset_iterate_dir(struct inode *inode, struct dir_context *ctx)
        while (true) {
                dentry = offset_find_next(&xas);
                if (!dentry)
-                       break;
+                       return ERR_PTR(-ENOENT);
 
                if (!offset_dir_emit(ctx, dentry)) {
                        dput(dentry);
@@ -444,6 +446,7 @@ static void offset_iterate_dir(struct inode *inode, struct dir_context *ctx)
                dput(dentry);
                ctx->pos = xas.xa_index + 1;
        }
+       return NULL;
 }
 
 /**
@@ -476,7 +479,12 @@ static int offset_readdir(struct file *file, struct dir_context *ctx)
        if (!dir_emit_dots(file, ctx))
                return 0;
 
-       offset_iterate_dir(d_inode(dir), ctx);
+       /* In this case, ->private_data is protected by f_pos_lock */
+       if (ctx->pos == 2)
+               file->private_data = NULL;
+       else if (file->private_data == ERR_PTR(-ENOENT))
+               return 0;
+       file->private_data = offset_iterate_dir(d_inode(dir), ctx);
        return 0;
 }
 
@@ -541,7 +549,8 @@ void simple_recursive_removal(struct dentry *dentry,
                                dput(victim);           // unpin it
                        }
                        if (victim == dentry) {
-                               inode->i_mtime = inode_set_ctime_current(inode);
+                               inode_set_mtime_to_ts(inode,
+                                                     inode_set_ctime_current(inode));
                                if (d_is_dir(dentry))
                                        drop_nlink(inode);
                                inode_unlock(inode);
@@ -582,7 +591,7 @@ static int pseudo_fs_fill_super(struct super_block *s, struct fs_context *fc)
         */
        root->i_ino = 1;
        root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
-       root->i_atime = root->i_mtime = inode_set_ctime_current(root);
+       simple_inode_init_ts(root);
        s->s_root = d_make_root(root);
        if (!s->s_root)
                return -ENOMEM;
@@ -638,8 +647,8 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den
 {
        struct inode *inode = d_inode(old_dentry);
 
-       dir->i_mtime = inode_set_ctime_to_ts(dir,
-                                            inode_set_ctime_current(inode));
+       inode_set_mtime_to_ts(dir,
+                             inode_set_ctime_to_ts(dir, inode_set_ctime_current(inode)));
        inc_nlink(inode);
        ihold(inode);
        dget(dentry);
@@ -673,8 +682,8 @@ int simple_unlink(struct inode *dir, struct dentry *dentry)
 {
        struct inode *inode = d_inode(dentry);
 
-       dir->i_mtime = inode_set_ctime_to_ts(dir,
-                                            inode_set_ctime_current(inode));
+       inode_set_mtime_to_ts(dir,
+                             inode_set_ctime_to_ts(dir, inode_set_ctime_current(inode)));
        drop_nlink(inode);
        dput(dentry);
        return 0;
@@ -709,9 +718,10 @@ void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry,
 {
        struct inode *newino = d_inode(new_dentry);
 
-       old_dir->i_mtime = inode_set_ctime_current(old_dir);
+       inode_set_mtime_to_ts(old_dir, inode_set_ctime_current(old_dir));
        if (new_dir != old_dir)
-               new_dir->i_mtime = inode_set_ctime_current(new_dir);
+               inode_set_mtime_to_ts(new_dir,
+                                     inode_set_ctime_current(new_dir));
        inode_set_ctime_current(d_inode(old_dentry));
        if (newino)
                inode_set_ctime_current(newino);
@@ -926,7 +936,7 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
         */
        inode->i_ino = 1;
        inode->i_mode = S_IFDIR | 0755;
-       inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
+       simple_inode_init_ts(inode);
        inode->i_op = &simple_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
        set_nlink(inode, 2);
@@ -952,7 +962,7 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
                        goto out;
                }
                inode->i_mode = S_IFREG | files->mode;
-               inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
+               simple_inode_init_ts(inode);
                inode->i_fop = files->ops;
                inode->i_ino = i;
                d_add(dentry, inode);
@@ -1520,7 +1530,7 @@ struct inode *alloc_anon_inode(struct super_block *s)
        inode->i_uid = current_fsuid();
        inode->i_gid = current_fsgid();
        inode->i_flags |= S_PRIVATE;
-       inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
+       simple_inode_init_ts(inode);
        return inode;
 }
 EXPORT_SYMBOL(alloc_anon_inode);
@@ -1912,3 +1922,20 @@ ssize_t direct_write_fallback(struct kiocb *iocb, struct iov_iter *iter,
        return direct_written + buffered_written;
 }
 EXPORT_SYMBOL_GPL(direct_write_fallback);
+
+/**
+ * simple_inode_init_ts - initialize the timestamps for a new inode
+ * @inode: inode to be initialized
+ *
+ * When a new inode is created, most filesystems set the timestamps to the
+ * current time. Add a helper to do this.
+ */
+struct timespec64 simple_inode_init_ts(struct inode *inode)
+{
+       struct timespec64 ts = inode_set_ctime_current(inode);
+
+       inode_set_atime_to_ts(inode, ts);
+       inode_set_mtime_to_ts(inode, ts);
+       return ts;
+}
+EXPORT_SYMBOL(simple_inode_init_ts);