On Wed, 4 Aug 2010 16:11:46 +0200 Stefan Metzmacher <metze@xxxxxxxxx> wrote: > Signed-off-by: Stefan Metzmacher <metze@xxxxxxxxx> > --- > fs/cifs/link.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 65 insertions(+), 0 deletions(-) > > diff --git a/fs/cifs/link.c b/fs/cifs/link.c > index 0d90a89..6cd0879 100644 > --- a/fs/cifs/link.c > +++ b/fs/cifs/link.c > @@ -114,6 +114,71 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr, > const unsigned char *path, > struct cifs_sb_info *cifs_sb, int xid) > { > + int rc; > + int oplock = 0; > + __u16 netfid = 0; > + struct cifsTconInfo *pTcon = cifs_sb->tcon; > + u8 *buf; > + char *pbuf; > + unsigned int bytes_read = 0; > + int buf_type = CIFS_NO_BUFFER; > + unsigned int link_len = 0; > + FILE_ALL_INFO file_info; > + > + if (!(fattr->cf_mode & S_IFREG)) > + /* it's not a symlink */ > + return 0; > + > + if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE) > + /* it's not a symlink */ > + return 0; > + > + buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); > + if (!buf) > + return -ENOMEM; > + pbuf = buf; > + > + rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, > + CREATE_NOT_DIR, &netfid, &oplock, &file_info, > + cifs_sb->local_nls, > + cifs_sb->mnt_cifs_flags & > + CIFS_MOUNT_MAP_SPECIAL_CHR); > + if (rc != 0) { > + kfree(buf); > + return rc; > + } > + > + if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) { > + CIFSSMBClose(xid, pTcon, netfid); > + kfree(buf); > + /* it's not a symlink */ > + return 0; > + } > + Might be better to move the kmalloc() here. If the open fails, or the size is wrong you won't need the buffer. Allocating memory can lead to reclaim events too, so it's best not to do it unless you really need it. > + /* Read header */ > + rc = CIFSSMBRead(xid, pTcon, netfid, > + CIFS_MF_SYMLINK_FILE_SIZE /* length */, > + 0 /* offset */, > + &bytes_read, &pbuf, &buf_type); > + CIFSSMBClose(xid, pTcon, netfid); > + if (rc != 0) { > + kfree(buf); > + return rc; > + } > + > + rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL); > + kfree(buf); > + if (rc == -EINVAL) > + /* it's not a symlink */ > + return 0; > + if (rc != 0) > + return rc; > + > + /* it is a symlink */ > + fattr->cf_eof = link_len; > + fattr->cf_mode &= ~S_IFMT; > + fattr->cf_mode |= S_IFLNK; > + fattr->cf_dtype = DT_LNK; > return 0; > } > -- Jeff Layton <jlayton@xxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html