summaryrefslogtreecommitdiff
path: root/fs/adfs/dir_f.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2019-12-09 11:09:30 +0000
committerAl Viro <viro@zeniv.linux.org.uk>2020-01-20 20:12:41 -0500
commita317120bf7f8306b594ee650ee14f08a0e599602 (patch)
tree4725119a5fbeccba04b2babcc345c34fefa51478 /fs/adfs/dir_f.c
parentacf5f0be8a520c02bfed74cfc6735bf5fdd4a9e5 (diff)
fs/adfs: dir: add generic copy functions
Directories can span multiple buffers, and we currently open-code memcpy access to these buffers, including dealing with entries that are split across multiple buffers. Such code exists in both directory format implementations. Provide common functions to allow data to be copied from/to the directory buffers as if they were a contiguous set of buffers, and use them when accessing directories. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/adfs/dir_f.c')
-rw-r--r--fs/adfs/dir_f.c56
1 files changed, 9 insertions, 47 deletions
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c
index 80ac261b9ec4..3c3b423577d2 100644
--- a/fs/adfs/dir_f.c
+++ b/fs/adfs/dir_f.c
@@ -224,24 +224,12 @@ adfs_obj2dir(struct adfs_direntry *de, struct object_info *obj)
static int
__adfs_dir_get(struct adfs_dir *dir, int pos, struct object_info *obj)
{
- struct super_block *sb = dir->sb;
struct adfs_direntry de;
- int thissize, buffer, offset;
-
- buffer = pos >> sb->s_blocksize_bits;
-
- if (buffer > dir->nr_buffers)
- return -EINVAL;
-
- offset = pos & (sb->s_blocksize - 1);
- thissize = sb->s_blocksize - offset;
- if (thissize > 26)
- thissize = 26;
+ int ret;
- memcpy(&de, dir->bh[buffer]->b_data + offset, thissize);
- if (thissize != 26)
- memcpy(((char *)&de) + thissize, dir->bh[buffer + 1]->b_data,
- 26 - thissize);
+ ret = adfs_dir_copyfrom(&de, dir, pos, 26);
+ if (ret)
+ return ret;
if (!de.dirobname[0])
return -ENOENT;
@@ -254,42 +242,16 @@ __adfs_dir_get(struct adfs_dir *dir, int pos, struct object_info *obj)
static int
__adfs_dir_put(struct adfs_dir *dir, int pos, struct object_info *obj)
{
- struct super_block *sb = dir->sb;
struct adfs_direntry de;
- int thissize, buffer, offset;
-
- buffer = pos >> sb->s_blocksize_bits;
-
- if (buffer > dir->nr_buffers)
- return -EINVAL;
-
- offset = pos & (sb->s_blocksize - 1);
- thissize = sb->s_blocksize - offset;
- if (thissize > 26)
- thissize = 26;
+ int ret;
- /*
- * Get the entry in total
- */
- memcpy(&de, dir->bh[buffer]->b_data + offset, thissize);
- if (thissize != 26)
- memcpy(((char *)&de) + thissize, dir->bh[buffer + 1]->b_data,
- 26 - thissize);
+ ret = adfs_dir_copyfrom(&de, dir, pos, 26);
+ if (ret)
+ return ret;
- /*
- * update it
- */
adfs_obj2dir(&de, obj);
- /*
- * Put the new entry back
- */
- memcpy(dir->bh[buffer]->b_data + offset, &de, thissize);
- if (thissize != 26)
- memcpy(dir->bh[buffer + 1]->b_data, ((char *)&de) + thissize,
- 26 - thissize);
-
- return 0;
+ return adfs_dir_copyto(dir, pos, &de, 26);
}
/*