summaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsacl.h
diff options
context:
space:
mode:
authorShirish Pargaonkar <shirishpargaonkar@gmail.com>2011-04-22 12:09:36 -0500
committerSteve French <sfrench@us.ibm.com>2011-05-19 14:10:51 +0000
commit9409ae58e0759d010b347e7b19ebc90ab5d4b98f (patch)
tree7b64bf5100528daaaf9f29819c78c8fe46b51af4 /fs/cifs/cifsacl.h
parent4d79dba0e00749fa40de8ef13a9b85ce57a1603b (diff)
downloadlinux-stable-9409ae58e0759d010b347e7b19ebc90ab5d4b98f.tar.gz
linux-stable-9409ae58e0759d010b347e7b19ebc90ab5d4b98f.tar.bz2
linux-stable-9409ae58e0759d010b347e7b19ebc90ab5d4b98f.zip
cifs: Invoke id mapping functions (try #17 repost)
rb tree search and insertion routines. A SID which needs to be mapped, is looked up in one of the rb trees depending on whether SID is either owner or group SID. If found in the tree, a (mapped) id from that node is assigned to uid or gid as appropriate. If unmapped, an upcall is attempted to map the SID to an id. If upcall is successful, node is marked as mapped. If upcall fails, node stays marked as unmapped and a mapping is attempted again only after an arbitrary time period has passed. To map a SID, which can be either a Owner SID or a Group SID, key description starts with the string "os" or "gs" followed by SID converted to a string. Without "os" or "gs", cifs.upcall does not know whether SID needs to be mapped to either an uid or a gid. Nodes in rb tree have fields to prevent multiple upcalls for a SID. Searching, adding, and removing nodes is done within global locks. Whenever a node is either found or inserted in a tree, a reference is taken on that node. Shrinker routine prunes a node if it has expired but does not prune an expired node if its refcount is not zero (i.e. sid/id of that node is_being/will_be accessed). Thus a node, if its SID needs to be mapped by making an upcall, can safely stay and its fields accessed without shrinker pruning it. A reference (refcount) is put on the node without holding the spinlock but a reference is get on the node by holding the spinlock. Every time an existing mapped node is accessed or mapping is attempted, its timestamp is updated to prevent it from getting erased or a to prevent multiple unnecessary repeat mapping retries respectively. For now, cifs.upcall is only used to map a SID to an id (uid or gid) but it would be used to obtain an SID for an id. Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifsacl.h')
-rw-r--r--fs/cifs/cifsacl.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index c4ae7d036563..757cf5aec3ee 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -39,6 +39,15 @@
#define ACCESS_ALLOWED 0
#define ACCESS_DENIED 1
+#define SIDOWNER 1
+#define SIDGROUP 2
+#define SIDLEN 150 /* S- 1 revision- 6 authorities- max 5 sub authorities */
+
+#define SID_ID_MAPPED 0
+#define SID_ID_PENDING 1
+#define SID_MAP_EXPIRE (3600 * HZ) /* map entry expires after one hour */
+#define SID_MAP_RETRY (300 * HZ) /* wait 5 minutes for next attempt to map */
+
struct cifs_ntsd {
__le16 revision; /* revision level */
__le16 type;
@@ -74,6 +83,21 @@ struct cifs_wksid {
char sidname[SIDNAMELENGTH];
} __attribute__((packed));
+struct cifs_sid_id {
+ unsigned int refcount; /* increment with spinlock, decrement without */
+ unsigned long id;
+ unsigned long time;
+ unsigned long state;
+ char *sidstr;
+ struct rb_node rbnode;
+ struct cifs_sid sid;
+};
+
+#ifdef __KERNEL__
+extern struct key_type cifs_idmap_key_type;
+extern const struct cred *root_cred;
+#endif /* KERNEL */
+
extern int match_sid(struct cifs_sid *);
extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);