From 7ffec372458d163492e56e663a1b3a2d7be0a0a2 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 29 Sep 2010 19:51:11 -0400 Subject: cifs: add refcounted and timestamped container for holding tcons Eventually, we'll need to track the use of tcons on a per-sb basis, so that we know when it's ok to tear them down. Begin this conversion by adding a new "tcon_link" struct and accessors that get it. For now, the core data structures are untouched -- cifs_sb still just points to a single tcon and the pointers are just cast to deal with the accessor functions. A later patch will flesh this out. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/xattr.c | 60 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'fs/cifs/xattr.c') diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 41f95bf6797..a264b744bb4 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -47,9 +47,10 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) #ifdef CONFIG_CIFS_XATTR int xid; struct cifs_sb_info *cifs_sb; + struct tcon_link *tlink; struct cifsTconInfo *pTcon; struct super_block *sb; - char *full_path; + char *full_path = NULL; if (direntry == NULL) return -EIO; @@ -58,16 +59,19 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) sb = direntry->d_inode->i_sb; if (sb == NULL) return -EIO; - xid = GetXid(); cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb_tcon(cifs_sb); + tlink = cifs_sb_tlink(cifs_sb); + if (IS_ERR(tlink)) + return PTR_ERR(tlink); + pTcon = tlink_tcon(tlink); + + xid = GetXid(); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { rc = -ENOMEM; - FreeXid(xid); - return rc; + goto remove_ea_exit; } if (ea_name == NULL) { cFYI(1, "Null xattr names not supported"); @@ -91,6 +95,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) remove_ea_exit: kfree(full_path); FreeXid(xid); + cifs_put_tlink(tlink); #endif return rc; } @@ -102,6 +107,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, #ifdef CONFIG_CIFS_XATTR int xid; struct cifs_sb_info *cifs_sb; + struct tcon_link *tlink; struct cifsTconInfo *pTcon; struct super_block *sb; char *full_path; @@ -113,16 +119,19 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, sb = direntry->d_inode->i_sb; if (sb == NULL) return -EIO; - xid = GetXid(); cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb_tcon(cifs_sb); + tlink = cifs_sb_tlink(cifs_sb); + if (IS_ERR(tlink)) + return PTR_ERR(tlink); + pTcon = tlink_tcon(tlink); + + xid = GetXid(); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { rc = -ENOMEM; - FreeXid(xid); - return rc; + goto set_ea_exit; } /* return dos attributes as pseudo xattr */ /* return alt name if available as pseudo attr */ @@ -132,9 +141,8 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, returns as xattrs */ if (value_size > MAX_EA_VALUE_SIZE) { cFYI(1, "size of EA value too large"); - kfree(full_path); - FreeXid(xid); - return -EOPNOTSUPP; + rc = -EOPNOTSUPP; + goto set_ea_exit; } if (ea_name == NULL) { @@ -198,6 +206,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, set_ea_exit: kfree(full_path); FreeXid(xid); + cifs_put_tlink(tlink); #endif return rc; } @@ -209,6 +218,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, #ifdef CONFIG_CIFS_XATTR int xid; struct cifs_sb_info *cifs_sb; + struct tcon_link *tlink; struct cifsTconInfo *pTcon; struct super_block *sb; char *full_path; @@ -221,16 +231,18 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, if (sb == NULL) return -EIO; - xid = GetXid(); - cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb_tcon(cifs_sb); + tlink = cifs_sb_tlink(cifs_sb); + if (IS_ERR(tlink)) + return PTR_ERR(tlink); + pTcon = tlink_tcon(tlink); + + xid = GetXid(); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { rc = -ENOMEM; - FreeXid(xid); - return rc; + goto get_ea_exit; } /* return dos attributes as pseudo xattr */ /* return alt name if available as pseudo attr */ @@ -323,6 +335,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, get_ea_exit: kfree(full_path); FreeXid(xid); + cifs_put_tlink(tlink); #endif return rc; } @@ -333,6 +346,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) #ifdef CONFIG_CIFS_XATTR int xid; struct cifs_sb_info *cifs_sb; + struct tcon_link *tlink; struct cifsTconInfo *pTcon; struct super_block *sb; char *full_path; @@ -346,18 +360,20 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) return -EIO; cifs_sb = CIFS_SB(sb); - pTcon = cifs_sb_tcon(cifs_sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) return -EOPNOTSUPP; + tlink = cifs_sb_tlink(cifs_sb); + if (IS_ERR(tlink)) + return PTR_ERR(tlink); + pTcon = tlink_tcon(tlink); + xid = GetXid(); full_path = build_path_from_dentry(direntry); if (full_path == NULL) { rc = -ENOMEM; - FreeXid(xid); - return rc; + goto list_ea_exit; } /* return dos attributes as pseudo xattr */ /* return alt name if available as pseudo attr */ @@ -370,8 +386,10 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); +list_ea_exit: kfree(full_path); FreeXid(xid); + cifs_put_tlink(tlink); #endif return rc; } -- cgit v1.2.3