aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/xattr.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-09-29 19:51:11 -0400
committerSteve French <sfrench@us.ibm.com>2010-10-06 16:12:44 +0000
commit7ffec372458d163492e56e663a1b3a2d7be0a0a2 (patch)
treee404e3d1000ff41e9b27d0ecb4d6a47187e110d7 /fs/cifs/xattr.c
parentf3983c2133e9bea9c8b4f690737d15e3e9b02491 (diff)
downloadkernel_samsung_smdk4412-7ffec372458d163492e56e663a1b3a2d7be0a0a2.tar.gz
kernel_samsung_smdk4412-7ffec372458d163492e56e663a1b3a2d7be0a0a2.tar.bz2
kernel_samsung_smdk4412-7ffec372458d163492e56e663a1b3a2d7be0a0a2.zip
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 <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/xattr.c')
-rw-r--r--fs/cifs/xattr.c60
1 files changed, 39 insertions, 21 deletions
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;
}