summaryrefslogtreecommitdiff
path: root/fs/affs/symlink.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-01-24 00:04:07 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-02-09 04:50:48 -0800
commitd842c31e636e5dbc85c3c75d1b964a6ff6e4daeb (patch)
tree4494d76ed1e2174854949f2ce4f47306f9be8b8f /fs/affs/symlink.c
parent36a0a4afb2e996f59651a845e5680d2f80cc6f23 (diff)
Fix remount races with symlink handling in affs
commit 29333920a5a46edcc9b728e2cf0134d5a9b516ee upstream. A couple of fields in affs_sb_info is used in follow_link() and symlink() for handling AFFS "absolute" symlinks. Need locking against affs_remount() updates. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/affs/symlink.c')
-rw-r--r--fs/affs/symlink.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c
index 41782539c907..ee00f08c4f53 100644
--- a/fs/affs/symlink.c
+++ b/fs/affs/symlink.c
@@ -20,7 +20,6 @@ static int affs_symlink_readpage(struct file *file, struct page *page)
int i, j;
char c;
char lc;
- char *pf;
pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino);
@@ -32,11 +31,15 @@ static int affs_symlink_readpage(struct file *file, struct page *page)
j = 0;
lf = (struct slink_front *)bh->b_data;
lc = 0;
- pf = AFFS_SB(inode->i_sb)->s_prefix ? AFFS_SB(inode->i_sb)->s_prefix : "/";
if (strchr(lf->symname,':')) { /* Handle assign or volume name */
+ struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);
+ char *pf;
+ spin_lock(&sbi->symlink_lock);
+ pf = sbi->s_prefix ? sbi->s_prefix : "/";
while (i < 1023 && (c = pf[i]))
link[i++] = c;
+ spin_unlock(&sbi->symlink_lock);
while (i < 1023 && lf->symname[j] != ':')
link[i++] = lf->symname[j++];
if (i < 1023)