]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
udf: store cookie in private data
authorChristian Brauner <brauner@kernel.org>
Fri, 30 Aug 2024 13:04:56 +0000 (15:04 +0200)
committerChristian Brauner <brauner@kernel.org>
Thu, 12 Sep 2024 09:58:44 +0000 (11:58 +0200)
Store the cookie to detect concurrent seeks on directories in
file->private_data.

Link: https://lore.kernel.org/r/20240830-vfs-file-f_version-v1-15-6d3e4816aa7b@kernel.org
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/udf/dir.c

index f94f45fe2c91e3f0167f36da97153f529e7de426..5023dfe191e8088b78396997a8915bf383f7a2d2 100644 (file)
@@ -60,7 +60,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
         * identifying beginning of dir entry (names are under user control),
         * we need to scan the directory from the beginning.
         */
-       if (!inode_eq_iversion(dir, file->f_version)) {
+       if (!inode_eq_iversion(dir, *(u64 *)file->private_data)) {
                emit_pos = nf_pos;
                nf_pos = 0;
        } else {
@@ -122,15 +122,37 @@ out_iter:
        udf_fiiter_release(&iter);
 out:
        if (pos_valid)
-               file->f_version = inode_query_iversion(dir);
+               *(u64 *)file->private_data = inode_query_iversion(dir);
        kfree(fname);
 
        return ret;
 }
 
+static int udf_dir_open(struct inode *inode, struct file *file)
+{
+       file->private_data = kzalloc(sizeof(u64), GFP_KERNEL);
+       if (!file->private_data)
+               return -ENOMEM;
+       return 0;
+}
+
+static int udf_dir_release(struct inode *inode, struct file *file)
+{
+       kfree(file->private_data);
+       return 0;
+}
+
+static loff_t udf_dir_llseek(struct file *file, loff_t offset, int whence)
+{
+       return generic_llseek_cookie(file, offset, whence,
+                                    (u64 *)file->private_data);
+}
+
 /* readdir and lookup functions */
 const struct file_operations udf_dir_operations = {
-       .llseek                 = generic_file_llseek,
+       .open                   = udf_dir_open,
+       .release                = udf_dir_release,
+       .llseek                 = udf_dir_llseek,
        .read                   = generic_read_dir,
        .iterate_shared         = udf_readdir,
        .unlocked_ioctl         = udf_ioctl,