diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 10:48:30 +0100 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 10:48:30 +0100 |
commit | 617677295b53a40d0e54aac4cbbc216ffbc755dd (patch) | |
tree | 51b9e87213243ed5efff252c8e8d8fec4eebc588 /fs/cifs/dir.c | |
parent | 5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff) | |
parent | 6abb7c25775b7fb2225ad0508236d63ca710e65f (diff) |
Merge branch 'master' into for-next
Conflicts:
drivers/devfreq/exynos4_bus.c
Sync with Linus' tree to be able to apply patches that are
against newer code (mvneta).
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 7c0a81283645..8719bbe0dcc3 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -44,6 +44,38 @@ renew_parental_timestamps(struct dentry *direntry) } while (!IS_ROOT(direntry)); } +char * +cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, + struct cifs_tcon *tcon) +{ + int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0; + int dfsplen; + char *full_path = NULL; + + /* if no prefix path, simply set path to the root of share to "" */ + if (pplen == 0) { + full_path = kzalloc(1, GFP_KERNEL); + return full_path; + } + + if (tcon->Flags & SMB_SHARE_IS_IN_DFS) + dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); + else + dfsplen = 0; + + full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL); + if (full_path == NULL) + return full_path; + + if (dfsplen) + strncpy(full_path, tcon->treeName, dfsplen); + full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb); + strncpy(full_path + dfsplen + 1, vol->prepath, pplen); + convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); + full_path[dfsplen + pplen] = 0; /* add trailing null */ + return full_path; +} + /* Note: caller must free return buffer */ char * build_path_from_dentry(struct dentry *direntry) @@ -398,7 +430,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, * in network traffic in the other paths. */ if (!(oflags & O_CREAT)) { - struct dentry *res = cifs_lookup(inode, direntry, 0); + struct dentry *res; + + /* + * Check for hashed negative dentry. We have already revalidated + * the dentry and it is fine. No need to perform another lookup. + */ + if (!d_unhashed(direntry)) + return -ENOENT; + + res = cifs_lookup(inode, direntry, 0); if (IS_ERR(res)) return PTR_ERR(res); |