📄 smbsharedfile.c
字号:
#include "headers.h"typedef struct SmbSharedFileEntry SmbSharedFileEntry;struct SmbSharedFileEntry { SmbSharedFile; Ref; SmbSharedFileEntry *next;};static struct { QLock; SmbSharedFileEntry *list;} sharedfiletable;typedef struct SmbLockListEntry SmbLockListEntry;struct SmbLockListEntry { SmbLock; SmbLockListEntry *next;};struct SmbLockList { SmbLockListEntry *head;};static intlockconflict(SmbLock *l1, SmbLock *l2){ return l1->base < l2->limit && l2->base < l1->limit;}static intlockorder(SmbLock *l1, SmbLock *l2){ if (l1->base < l2->base) return -1; if (l1->base > l2->base) return 1; if (l1->limit > l2->limit) return -1; if (l1->limit < l2->limit) return 1; return 0;}static voidlocklistfree(SmbLockList **llp){ SmbLockList *ll = *llp; if (ll) { while (ll->head) { SmbLockListEntry *next = ll->head->next; free(ll->head); ll->head = next; } free(ll); *llp = nil; }}intsmbsharedfilelock(SmbSharedFile *sf, SmbSession *s, ushort pid, vlong base, vlong limit){ SmbLockListEntry smblock; SmbLockListEntry *l, *nl, **lp; smblock.s = s; smblock.pid = pid; smblock.base = base; smblock.limit = limit; if (sf->locklist) { for (l = sf->locklist->head; l; l = l->next) if (lockconflict(l, &smblock)) { smblogprintif(smbglobals.log.locks, "smbsharedfilelock: lock [%lld, %lld) failed because conflicts with [%lld, %lld)\n", base, limit, l->base, l->limit); return 0; } } if (sf->locklist == nil) sf->locklist = smbemallocz(sizeof(SmbLockList), 1); for (lp = &sf->locklist->head; (l = *lp) != nil; lp = &l->next) if (lockorder(&smblock, l) <= 0) break; smblogprintif(smbglobals.log.locks, "smbsharedfilelock: lock [%lld, %lld) succeeded\n", base, limit); nl = smbemalloc(sizeof(*nl)); *nl = smblock; nl->next = *lp; *lp = nl;//{// smblogprintif(smbglobals.log.locks,"smbsharedfilelock: list\n");// for (l = sf->locklist->head; l; l = l->next)// smblogprintif(smbglobals.log.locks, "smbsharedfilelock: [%lld, %lld)\n", l->base, l->limit);//} return 1;}intsmbsharedfileunlock(SmbSharedFile *sf, SmbSession *s, ushort pid, vlong base, vlong limit){ SmbLockListEntry smblock; SmbLockListEntry *l, **lp; smblock.s = s; smblock.pid = pid; smblock.base = base; smblock.limit = limit; if (sf->locklist == nil) goto failed; for (lp = &sf->locklist->head; (l = *lp) != nil; lp = &l->next) { if (l->s != s || l->pid != pid) continue; switch (lockorder(&smblock, l)) { case 0: *lp = l->next; free(l); smblogprintif(smbglobals.log.locks, "smbsharedfilelock: unlock [%lld, %lld) succeeded\n", base, limit); return 1; case -1: goto failed; } }failed: smblogprintif(smbglobals.log.locks, "smbsharedfilelock: unlock [%lld, %lld) failed\n", base, limit); return 0;}static intp9denied(int p9mode, int share){//smblogprint(-1, "p9denied(%d, %d)\n", p9mode, share); if (share == SMB_OPEN_MODE_SHARE_EXCLUSIVE) return 1; switch (p9mode & 3) { case OREAD: case OEXEC: if (share == SMB_OPEN_MODE_SHARE_DENY_READOREXEC) return 1; break; case OWRITE: if (share == SMB_OPEN_MODE_SHARE_DENY_WRITE) return 1; break; case ORDWR: if (share != SMB_OPEN_MODE_SHARE_DENY_NONE) return 1; break; } return 0;}static voidsharesplit(int share, int *denyread, int *denywrite){ switch (share) { case SMB_OPEN_MODE_SHARE_EXCLUSIVE: *denyread = 1; *denywrite = 1; break; case SMB_OPEN_MODE_SHARE_DENY_READOREXEC: *denyread = 1; *denywrite = 0; break; case SMB_OPEN_MODE_SHARE_DENY_WRITE: *denywrite = 0; *denywrite = 1; break; default: *denyread = 0; *denywrite = 0; }}static intsharemake(int denyread, int denywrite){ if (denyread) if (denywrite) return SMB_OPEN_MODE_SHARE_EXCLUSIVE; else return SMB_OPEN_MODE_SHARE_DENY_READOREXEC; else if (denywrite) return SMB_OPEN_MODE_SHARE_DENY_WRITE; else return SMB_OPEN_MODE_SHARE_DENY_NONE;}static ushortsharesubtract(int share1, int share2){ int dr1, dw1; int dr2, dw2; sharesplit(share1, &dr1, &dw1); sharesplit(share2, &dr2, &dw2); if (dw2) dw1 = 0; if (dr2) dr1 = 0; return sharemake(dr1, dw1);}static intshareadd(int share1, int share2){ int dr1, dw1; int dr2, dw2; sharesplit(share1, &dr1, &dw1); sharesplit(share2, &dr2, &dw2); if (dw2) dw1 = 1; if (dr2) dr1 = 1; return sharemake(dr1, dw1);}SmbSharedFile *smbsharedfileget(Dir *d, int p9mode, int *sharep){ SmbSharedFileEntry *sfe; qlock(&sharedfiletable); for (sfe = sharedfiletable.list; sfe; sfe = sfe->next) { if (sfe->type == d->type && sfe->dev == d->dev && sfe->path == d->qid.path) { if (p9denied(p9mode, sfe->share)) { qunlock(&sharedfiletable); return nil; } *sharep = sharesubtract(*sharep, sfe->share); sfe->share = shareadd(sfe->share, *sharep); sfe->ref++; goto done; } } sfe = smbemallocz(sizeof(SmbSharedFileEntry), 1); sfe->type = d->type; sfe->dev = d->dev; sfe->path = d->qid.path;// sfe->name = smbestrdup(name); sfe->ref = 1; sfe->share = *sharep; sfe->next = sharedfiletable.list; sharedfiletable.list = sfe;done: smblogprintif(smbglobals.log.sharedfiles, "smbsharedfileget: ref %d share %d\n", sfe->ref, sfe->share); qunlock(&sharedfiletable); return sfe;}voidsmbsharedfileput(SmbFile *f, SmbSharedFile *sf, int share){ SmbSharedFileEntry *sfe, **sfep; qlock(&sharedfiletable); for (sfep = &sharedfiletable.list; (sfe = *sfep) != nil; sfep = &sfe->next) { if (sfe == sf) { sfe->ref--; if (sfe->ref == 0) { *sfep = sfe->next; if (sfe->deleteonclose && f) smbremovefile(f->t, nil, f->name); smblogprintif(smbglobals.log.sharedfiles, "smbsharedfileput: removed\n"); locklistfree(&sfe->locklist); free(sfe); } else { sfe->share = sharesubtract(sfe->share, share); smblogprintif(smbglobals.log.sharedfiles, "smbsharedfileput: ref %d share %d\n", sfe->ref, sfe->share); } break; } } qunlock(&sharedfiletable);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -